arrow_backRetour aux issues
MakazhanAlpamys/Soup
#427
Débutant
Ouvrirarrow_forward
Débutant
Ouvrirarrow_forward
Débutant
Ouvrirarrow_forward
Nine Qwen3.5 recipes declare modality: text, but every checkpoint in the family reports a multimodal architecture
ecoDébutant
bug
help wanted
qa
descriptionDescription
## What is verified
All **nine** shipped Qwen3.5 recipes leave `modality` unset, so they take the schema default `text` (`config/schema.py:3998`):
```
qwen3.5-0.8b-sft Qwen/Qwen3.5-0.8B modality=(unset -> text)
qwen3.5-2b-sft Qwen/Qwen3.5-2B modality=(unset -> text)
qwen3.5-4b-sft Qwen/Qwen3.5-4B modality=(unset -> text)
qwen3.5-4b-pretrain Qwen/Qwen3.5-4B-Base modality=(unset -> text)
qwen3.5-9b-sft Qwen/Qwen3.5-9B modality=(unset -> text)
qwen3.5-27b-sft Qwen/Qwen3.5-27B modality=(unset -> text)
qwen3.5-35b-a3b-sft Qwen/Qwen3.5-35B-A3B modality=(unset -> text)
qwen3.5-122b-a10b-sft Qwen/Qwen3.5-122B-A10B modality=(unset -> text)
qwen3.5-397b-a17b-sft Qwen/Qwen3.5-397B-A17B modality=(unset -> text)
```
Every one of those checkpoints reports a **multimodal** architecture on the Hub, uniformly across the family — dense and MoE alike:
```
Qwen/Qwen3.5-0.8B -> image-text-to-text | ['Qwen3_5ForConditionalGeneration']
Qwen/Qwen3.5-4B -> image-text-to-text | ['Qwen3_5ForConditionalGeneration']
Qwen/Qwen3.5-4B-Base -> image-text-to-text | ['Qwen3_5ForConditionalGeneration']
Qwen/Qwen3.5-27B -> image-text-to-text | ['Qwen3_5ForConditionalGeneration']
Qwen/Qwen3.5-35B-A3B -> image-text-to-text | ['Qwen3_5MoeForConditionalGeneration']
```
Control, so this is a real distinction and not an artefact of how I queried:
```
Qwen/Qwen2.5-7B -> text-generation | ['Qwen2ForCausalLM']
```
## What is NOT verified, and I want to be explicit about it
**I have not run one of these recipes.** I am not claiming they fail. `ForConditionalGeneration` checkpoints are frequently loadable through a text-only causal-LM path, and the text path may well be exactly right here.
What I am claiming is narrower: **nine shipped recipes assert a modality that the checkpoint's own architecture contradicts, and no one has checked which of the two is wrong.** That is a claim about our evidence, not about the code.
## Why it is worth resolving rather than leaving
Two concrete places it could bite:
1. If the text path silently loads only the language tower, a user gets a run that trains and saves and looks healthy while quietly ignoring part of the model. This project has shipped that failure shape **three times** (`.inner.` keys in v0.72.0, the full-fine-tune adapter in #362, `target_modules: auto` in #392) and the recorded lesson each time is the same: a healthy loss curve structurally cannot see it.
2. The `Qwen/Qwen3.5-4B-Base` config appears to carry no top-level `vocab_size`. Any code path reading `AutoConfig.vocab_size` directly would refuse or misread it — PR #409 introduces exactly such a read in `soup draft`, and this was raised there separately.
## Acceptance criteria
- [ ] Load one Qwen3.5 checkpoint through the `modality: text` SFT path and record what is actually instantiated — full model or language tower only.
- [ ] Decide: recipes get `modality: vision`, **or** `text` is correct and the reason is written down so the next person does not re-open this.
- [ ] If `text` is correct, add a test asserting it deliberately, so the agreement is pinned rather than incidental.
- [ ] Audit for other families in the catalog whose declared modality disagrees with the Hub architecture — a one-off fix here leaves the class open.
## Not the contributor's doing
Flagged while reviewing #422, which added the ninth recipe by copying the eight that preceded it — exactly as the issue asked. This is a pre-existing family-wide question, deliberately not loaded onto a first contribution.
Issues similaires
calkit/calkit
star53
Poids du dépôt moyen
VS Code extension should be robust to YAML parser errors
Seeing this error: ``` Failed to read calkit.yaml: YAMLParseError: A block sequence may not be used as an implicit map…
Python
bug
good first issue
fu351/Doberman-Core
star211
Poids du dépôt léger
dash: a manual Refresh control
The dashboard polls: `refreshStats()` (`src/doberman/dash/app.py:408`) every 5 s and `refreshPending()` (`:546`) every …
Python
enhancement
good first issue
fu351/Doberman-Core
star211
Poids du dépôt léger
dash: "Copy details" button on each pending-approval card
Each pending-approval card in the dashboard (`renderPending`, `src/doberman/dash/app.py:448-544`) shows the risk badge,…
Python
enhancement
good first issue