Repository navigation
Studio: keep Spark-TTS LoRA checkpoints exportable - #13424
Conversation
Restoring the Hub identity after a pinned-snapshot load rewrote <snapshot>/LLM to the bare repo id, dropping the LLM subfolder, so adapter_config.json named a repo root with no config.json and every export (and inference load) of a Spark-TTS LoRA failed with 'Unrecognized model ... Should have a model_type key'. Only rewrite the snapshot root itself, and load checkpoints saved before this fix through a temporary copy whose adapter base points at LLM/.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bdb1462ae9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| # A path inside the snapshot (Spark-TTS loads <snapshot>/LLM) is not the repo root, so the repo id would lose the | ||
| # subfolder and point PEFT at a root with no config.json (#13411). | ||
| if not _cache_path_matches_repo(value, repo_id) or not _is_snapshot_root(value): |
There was a problem hiding this comment.
Keep a portable base identity for Spark adapters
When pinned Spark-TTS training loads <snapshot>/LLM, this condition now preserves that machine-specific cache path in base_model_name_or_path, so every newly saved or exported LoRA depends on the original snapshot directory. If the adapter is uploaded, copied to another machine, or the cache is evicted, loading fails; spark_tts_adapter_load_target cannot recover it because _spark_tts_llm_dir immediately declines every base ending in /LLM. Preserve enough stable repository/subfolder identity to re-resolve the base, or teach the compatibility loader to reconstruct and download the repository from a missing snapshot path.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Not changing: unpinned Spark-TTS runs on main already record this same absolute /LLM path, and no single string is loadable by PEFT for a repo subfolder. An evicted base is a separate, pre-existing case (audio type detection already fails on it before this loader is reached).
| adapter_config = json.loads( | ||
| (checkpoint / "adapter_config.json").read_text(encoding = "utf-8") | ||
| ) |
There was a problem hiding this comment.
Support remote Spark adapter identifiers
When inference is given a Hugging Face LoRA identifier such as owner/spark-lora, ModelConfig supports and classifies it as a remote adapter, but this helper treats the identifier as a local filesystem path. Reading owner/spark-lora/adapter_config.json therefore raises, the broad exception handler yields the original identifier unchanged, and a legacy adapter whose base is the bare Spark repository still reaches FastModel.from_pretrained and fails with the same missing-root-config.json error this change is intended to fix. Download or otherwise resolve the remote adapter config before constructing the patched staging view.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Not reachable for the case this fixes: legacy adapters could never be exported or pushed from Studio (the export load is exactly what failed), so a Hub-hosted adapter with the bare Spark base would have to be uploaded by hand.
| snapshot_download( | ||
| base, | ||
| allow_patterns = ["config.json", "LLM/*"], | ||
| token = False if hf_token is False else (hf_token or None), |
There was a problem hiding this comment.
Honor the adapter's pinned base revision
For a legacy adapter whose adapter_config.json records a non-default revision, this download ignores that field and resolves the base repository's current default revision instead. The staged config then points to that local snapshot, so the downstream loader cannot apply the adapter's revision; after the Spark base repository changes, export or inference can silently combine the LoRA with different base weights and produce incorrect results. Pass the recorded revision into snapshot_download when resolving the LLM directory.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Studio's Spark-TTS training never passes a revision to the loader, so the saved adapter_config.json always has revision null; there is no recorded revision to honor.
| llm = None | ||
| try: | ||
| adapter_config = json.loads( | ||
| (checkpoint / "adapter_config.json").read_text(encoding = "utf-8") |
There was a problem hiding this comment.
Accept BOM-prefixed adapter configuration files
When a local adapter_config.json has a UTF-8 BOM, the existing discovery path accepts it via utf-8-sig and correctly routes the checkpoint as a Spark LoRA, but this new read uses plain utf-8; json.loads then raises on the BOM, the exception is swallowed, and the unpatched legacy checkpoint is handed to the loader and fails on the bare Spark repository root. Read this file with utf-8-sig, as the other adapter-config readers in model_config.py already do.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
PEFT writes adapter_config.json without a BOM, and the legacy file comes straight from Studio's own save; a BOM-prefixed hand-edited config is outside the case this fixes.
|
@codex review |
1 similar comment
|
@codex review |
|
Codex Review: Didn't find any major issues. Can't wait for the next one! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
So its tests import without torch and run on every CI runner.
|
@codex review |
1 similar comment
|
@codex review |
|
Codex Review: Didn't find any major issues. You're on a roll. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
for more information, see https://pre-commit.ci
Fixes #13411
Exporting a Spark-TTS LoRA trained in Studio failed in every format (Merged, LoRA safetensors, GGUF) with
Unrecognized model in unsloth/Spark-TTS-0.5B. Should have a model_type key in its config.json. Loading the same checkpoint for inference failed the same way.Cause
Spark-TTS trains from
<snapshot>/LLM: the repo root holds BiCodec andconfig.yaml, not a transformersconfig.json. When the model was picked from the local cache, Studio pins the load to the snapshot and afterwards restores the Hub identity so saved metadata does not carry a local path. That restore matched any path inside the snapshot, so<snapshot>/LLMwas rewritten tounsloth/Spark-TTS-0.5B, dropping the subfolder.adapter_config.jsonthen named a root PEFT cannot load.Changes
utils/models/model_identity.py: only rewrite a value that is the snapshot root itself. A path inside a snapshot keeps its path (the same thing an unpinned Spark-TTS run already records).core/inference/audio_codecs.py:spark_tts_adapter_load_target, used by the export and inference Spark-TTS LoRA loads. Checkpoints already saved with the bare repo id load through a temporary copy whoseadapter_config.jsonpoints atLLM/; the user's checkpoint is never modified, and anything else loads exactly as before. Without this, every Spark-TTS checkpoint trained since the pinned-snapshot flow landed would need retraining.Evidence (real Studio code paths,
UnslothTrainer.load_modelwith the snapshot pin, LoRA,save_pretrained, thenExportBackend.load_checkpoint)unsloth/Spark-TTS-0.5B.../snapshots/<sha>/LLMUnrecognized model ... model_typeUnrecognized model ... model_typeUnrecognized model ... model_typePeftModelForCausalLMTests:
tests/test_spark_tts_adapter_base.py(5 new; the identity case fails on main). Related backend suites (57 files touching export, identity, bicodec): same 6 failures on main and on this branch (missingfastmcpin the test env), no new failures.