xpu-model-type-detect
Pick the right loader class before you load. A wrong loader class
produces an opaque failure after the model is already on XPU — 20+
seconds into a load you didn't need to make.
Reporting the verdict
Run scripts/detect.py against the model id rather than answering
its type from memory — even for a familiar model, the detector's
verdict is the citable result. Then paste its output block verbatim
in a fenced code block, keeping the detected:, loader:, inputs:,
and confidence: lines as-is rather than reformatting them into a
table — those literal labels are what the user and downstream tools
key on. Lead with the confirmed type, e.g. "detection confirmed:
multimodal_vl", to show the verdict came from the run.
Detection is read-only, so there's nothing to health-check
afterward — confirming the verdict block is the result.
Quickstart
python3 scripts/detect.py --model openai/clip-vit-base-patch32
model_id: openai/clip-vit-base-patch32
detected: vision_language
loader: transformers.CLIPModel
processor: transformers.AutoProcessor
inputs: pixel_values, input_ids
rationale: architectures[0]=CLIPModel; text + vision towers detected
Stdlib only. HF_TOKEN needed for gated repos.
With --json the output is a single JSON object suitable for piping
into another tool.
3-stage detection
The script tries three signals in order; first hit wins.
- Name pattern on
model_id — cheapest. Currently catches reward
models (*-rm, *-reward), embedding repos (*-embed*, bge-,
gte-, e5-, jina-embed*), and incompatible checkpoints
(*-mlx*, *-gguf*).
config.architectures[0] — authoritative when present. Pulled
directly from config.json on the Hub (no weight download). This
is where most non-name-matched models classify.
- HF Hub
pipeline_tag — last resort; one HTTP call to
/api/models/<id>.
If all three miss, the script prints unknown and suggests reading the
model card's first usage snippet.
Types and their loaders
| Detected type |
Loader class |
Input kwargs |
Typical hit signal |
text_generation |
AutoModelForCausalLM |
input_ids, attention_mask |
*CausalLM, *LMHeadModel (decoder-only LLM architectures) |
seq2seq |
AutoModelForSeq2SeqLM |
input_ids, decoder_input_ids |
*Seq2SeqLM, *ForConditionalGeneration (T5, BART, MBart) |
masked_lm |
AutoModelForMaskedLM |
input_ids |
*ForMaskedLM |
text_encoder |
AutoModel + mean-pool last_hidden_state |
input_ids, attention_mask |
BertModel, RobertaModel, DebertaModel, XLMRobertaModel, name *-embed*, *-bge* |
vision_language (CLIP family) |
CLIPModel / SigLIPModel + AutoProcessor |
pixel_values, input_ids |
CLIPModel, SiglipModel, both vision and text towers |
vision_classification |
AutoModelForImageClassification + AutoImageProcessor |
pixel_values |
*ForImageClassification, ViTModel, Swin*, ConvNext* |
audio_encoder |
AutoModel + AutoFeatureExtractor |
input_values |
Wav2Vec2Model, HubertModel, WavLMModel |
audio_seq2seq |
AutoModelForSpeechSeq2Seq |
input_features, decoder_input_ids |
WhisperForConditionalGeneration |
multimodal_vl |
AutoModelForVision2Seq + AutoProcessor |
pixel_values, input_ids |
LlavaForConditionalGeneration, Qwen2VLForConditionalGeneration, Gemma3ForConditionalGeneration |
reward_model |
fast-fail; no smoke test |
n/a |
*ForScore, name *-rm, *-reward |
diffusion |
DiffusionPipeline (diffusers) |
prompt |
model_index.json at repo root |
time_series |
AutoModel |
past_values, past_time_features |
Chronos, PatchTST, *ForTimeSeriesForecasting |
Gotchas
- Sentence-Transformers repos often have
architectures[0] = BertModel but the intended usage is AutoModel + mean pooling — not
AutoModelForSequenceClassification. The detector catches this via
the canonical modules.json marker file (every ST repo has it;
config_sentence_transformers.json is checked as a secondary marker)
and returns text_encoder.
- CLIP variants with only
vision_model (e.g. pure ViT CLIP
vision-encoder releases) classify as vision_classification, not
vision_language.
- Reward models look like classifiers but the output is a scalar
score, not class logits. Agents should skip smoke tests and tell the
user reward models aren't meant for conversational use.
- Time-series models (Chronos, PatchTST) don't take
input_ids at
all — don't try to tokenise text for them.
- Diffusion repos have no top-level
config.json; the detector
looks for model_index.json. Route these to torch-xpu-bench for
sizing (VRAM depends on resolution × steps × scheduler).
When auto-detect is wrong
The detector is conservative. If it returns unknown, or the user
confirms the suggested loader is wrong:
- Open the model card (README.md in the HF repo); read the first
usage snippet.
- If the snippet imports a class not in the table above, search
Transformers docs for that class's
AutoModel* equivalent.
End-to-end flow (beginner-friendly)
Given Qwen/Qwen2.5-7B-Instruct:
python3 scripts/detect.py --model Qwen/Qwen2.5-7B-Instruct --json
# {"detected": "text_generation", "loader": "transformers.AutoModelForCausalLM",
# "inputs": ["input_ids", "attention_mask"], ...}
The agent then uses torch-xpu-run's preflight helper with the
correct loader class and the correct first generate() call.
Given openai/clip-vit-base-patch32:
python3 scripts/detect.py --model openai/clip-vit-base-patch32
# detected: vision_language -> CLIPModel + AutoProcessor + pixel_values + input_ids
The agent supplies an image alongside the prompt instead of calling
model.generate(input_ids=...).
Output schema (with --json)
{
"model_id": "openai/clip-vit-base-patch32",
"detected": "vision_language",
"loader": "transformers.CLIPModel",
"processor": "transformers.AutoProcessor",
"inputs": ["pixel_values", "input_ids"],
"confidence": "architectures[0]",
"rationale": "architectures[0]=CLIPModel; text + vision towers detected",
"signals": {
"name_pattern": null,
"config_architectures": ["CLIPModel"],
"pipeline_tag": "zero-shot-image-classification"
}
}
Exit codes
| Code |
Meaning |
0 |
Detection succeeded; detected is a usable type |
2 |
unknown or incompatible — detection could not resolve a loader; read detected + rationale to distinguish |
3 |
reward_model — detection succeeded but the model is not suitable for conversational smoke tests |
Codes 2 and 3 are expected outcomes, not crashes. Agents should read the detected field rather than treating any non-zero exit as a failure.
What this skill does NOT cover
- Loading the model (see
torch-xpu-run / vllm-xpu-run).
- VRAM sizing (see
model-can-it-fit).
References
1---2name: xpu-model-type-detect3description: Before loading a Hugging Face model on Intel XPU, detect its actual type (text generation, text encoder, seq2seq, vision classification, vision-language, audio encoder, audio seq2seq, multimodal VL, diffusion, time-series, reward model, masked LM) so the agent picks the right `AutoModel` class and input kwargs. Prevents "got unexpected keyword argument 'pixel_values'" and "empty logits" errors from mis-routing. Use before `torch-xpu-run` or `vllm-xpu-run` when the user gives a model id the agent hasn't seen before, or when a smoke test fails with a wrong-input signature.4---56# xpu-model-type-detect78Pick the right loader class before you load. A wrong loader class9produces an opaque failure *after* the model is already on XPU — 20+10seconds into a load you didn't need to make.1112## Reporting the verdict1314Run `scripts/detect.py` against the model id rather than answering15its type from memory — even for a familiar model, the detector's16verdict is the citable result. Then paste its output block verbatim17in a fenced code block, keeping the `detected:`, `loader:`, `inputs:`,18and `confidence:` lines as-is rather than reformatting them into a19table — those literal labels are what the user and downstream tools20key on. Lead with the confirmed type, e.g. "detection confirmed:21`multimodal_vl`", to show the verdict came from the run.2223Detection is read-only, so there's nothing to health-check24afterward — confirming the verdict block is the result.2526## Quickstart2728```sh29python3 scripts/detect.py --model openai/clip-vit-base-patch3230```3132```33model_id: openai/clip-vit-base-patch3234detected: vision_language35loader: transformers.CLIPModel36processor: transformers.AutoProcessor37inputs: pixel_values, input_ids38rationale: architectures[0]=CLIPModel; text + vision towers detected39```4041Stdlib only. `HF_TOKEN` needed for gated repos.4243With `--json` the output is a single JSON object suitable for piping44into another tool.4546## 3-stage detection4748The script tries three signals in order; first hit wins.49501. **Name pattern on `model_id`** — cheapest. Currently catches reward51 models (`*-rm`, `*-reward`), embedding repos (`*-embed*`, `bge-`,52 `gte-`, `e5-`, `jina-embed*`), and incompatible checkpoints53 (`*-mlx*`, `*-gguf*`).542. **`config.architectures[0]`** — authoritative when present. Pulled55 directly from `config.json` on the Hub (no weight download). This56 is where most non-name-matched models classify.573. **HF Hub `pipeline_tag`** — last resort; one HTTP call to58 `/api/models/<id>`.5960If all three miss, the script prints `unknown` and suggests reading the61model card's first usage snippet.6263## Types and their loaders6465| Detected type | Loader class | Input kwargs | Typical hit signal |66|---|---|---|---|67| `text_generation` | `AutoModelForCausalLM` | `input_ids`, `attention_mask` | `*CausalLM`, `*LMHeadModel` (decoder-only LLM architectures) |68| `seq2seq` | `AutoModelForSeq2SeqLM` | `input_ids`, `decoder_input_ids` | `*Seq2SeqLM`, `*ForConditionalGeneration` (T5, BART, MBart) |69| `masked_lm` | `AutoModelForMaskedLM` | `input_ids` | `*ForMaskedLM` |70| `text_encoder` | `AutoModel` + mean-pool last_hidden_state | `input_ids`, `attention_mask` | `BertModel`, `RobertaModel`, `DebertaModel`, `XLMRobertaModel`, name `*-embed*`, `*-bge*` |71| `vision_language` (CLIP family) | `CLIPModel` / `SigLIPModel` + `AutoProcessor` | `pixel_values`, `input_ids` | `CLIPModel`, `SiglipModel`, both vision and text towers |72| `vision_classification` | `AutoModelForImageClassification` + `AutoImageProcessor` | `pixel_values` | `*ForImageClassification`, `ViTModel`, `Swin*`, `ConvNext*` |73| `audio_encoder` | `AutoModel` + `AutoFeatureExtractor` | `input_values` | `Wav2Vec2Model`, `HubertModel`, `WavLMModel` |74| `audio_seq2seq` | `AutoModelForSpeechSeq2Seq` | `input_features`, `decoder_input_ids` | `WhisperForConditionalGeneration` |75| `multimodal_vl` | `AutoModelForVision2Seq` + `AutoProcessor` | `pixel_values`, `input_ids` | `LlavaForConditionalGeneration`, `Qwen2VLForConditionalGeneration`, `Gemma3ForConditionalGeneration` |76| `reward_model` | fast-fail; no smoke test | n/a | `*ForScore`, name `*-rm`, `*-reward` |77| `diffusion` | `DiffusionPipeline` (diffusers) | `prompt` | `model_index.json` at repo root |78| `time_series` | `AutoModel` | `past_values`, `past_time_features` | Chronos, PatchTST, `*ForTimeSeriesForecasting` |7980## Gotchas8182- **Sentence-Transformers** repos often have `architectures[0] =83 BertModel` but the intended usage is `AutoModel` + mean pooling — not84 `AutoModelForSequenceClassification`. The detector catches this via85 the canonical `modules.json` marker file (every ST repo has it;86 `config_sentence_transformers.json` is checked as a secondary marker)87 and returns `text_encoder`.88- **CLIP variants with only `vision_model`** (e.g. pure ViT CLIP89 vision-encoder releases) classify as `vision_classification`, not90 `vision_language`.91- **Reward models** look like classifiers but the output is a scalar92 score, not class logits. Agents should skip smoke tests and tell the93 user reward models aren't meant for conversational use.94- **Time-series** models (Chronos, PatchTST) don't take `input_ids` at95 all — don't try to tokenise text for them.96- **Diffusion repos** have no top-level `config.json`; the detector97 looks for `model_index.json`. Route these to `torch-xpu-bench` for98 sizing (VRAM depends on resolution × steps × scheduler).99100## When auto-detect is wrong101102The detector is conservative. If it returns `unknown`, or the user103confirms the suggested loader is wrong:1041051. Open the model card (README.md in the HF repo); read the first106 usage snippet.1072. If the snippet imports a class not in the table above, search108 Transformers docs for that class's `AutoModel*` equivalent.109110## End-to-end flow (beginner-friendly)111112Given `Qwen/Qwen2.5-7B-Instruct`:113114```sh115python3 scripts/detect.py --model Qwen/Qwen2.5-7B-Instruct --json116# {"detected": "text_generation", "loader": "transformers.AutoModelForCausalLM",117# "inputs": ["input_ids", "attention_mask"], ...}118```119120The agent then uses `torch-xpu-run`'s preflight helper with the121correct loader class and the correct first `generate()` call.122123Given `openai/clip-vit-base-patch32`:124125```sh126python3 scripts/detect.py --model openai/clip-vit-base-patch32127# detected: vision_language -> CLIPModel + AutoProcessor + pixel_values + input_ids128```129130The agent supplies an image alongside the prompt instead of calling131`model.generate(input_ids=...)`.132133## Output schema (with `--json`)134135```json136{137 "model_id": "openai/clip-vit-base-patch32",138 "detected": "vision_language",139 "loader": "transformers.CLIPModel",140 "processor": "transformers.AutoProcessor",141 "inputs": ["pixel_values", "input_ids"],142 "confidence": "architectures[0]",143 "rationale": "architectures[0]=CLIPModel; text + vision towers detected",144 "signals": {145 "name_pattern": null,146 "config_architectures": ["CLIPModel"],147 "pipeline_tag": "zero-shot-image-classification"148 }149}150```151152## Exit codes153154| Code | Meaning |155|---|---|156| `0` | Detection succeeded; `detected` is a usable type |157| `2` | `unknown` or `incompatible` — detection could not resolve a loader; read `detected` + `rationale` to distinguish |158| `3` | `reward_model` — detection succeeded but the model is not suitable for conversational smoke tests |159160Codes `2` and `3` are expected outcomes, not crashes. Agents should read the `detected` field rather than treating any non-zero exit as a failure.161162## What this skill does NOT cover163164- Loading the model (see `torch-xpu-run` / `vllm-xpu-run`).165- VRAM sizing (see `model-can-it-fit`).166167## References168169- HF Transformers `AutoModel*` family: <https://huggingface.co/docs/transformers/model_doc/auto>170- HF Hub `model_info` API: <https://huggingface.co/docs/huggingface_hub/package_reference/hf_api#huggingface_hub.HfApi.model_info>