Views
No views yet
⚠️ Experimental early checkpoint. This is an intermediate training checkpoint (step 20500) from a tool-calling supervised fine-tuning (SFT) run on a Qwen3.5 ~4B base model. It is not a finished, fully-evaluated release. Behavior, quality, and the prompt/tool-call format may change in later checkpoints. Use for research and experimentation only.
Qwen3_5ForConditionalGeneration). It was produced by
an internal NVIDIA Nemotron "edge" experiment (codename steep_jellyfish) that
applies tool-calling / function-calling SFT on top of a Qwen3.5 4B-class base
model. It accepts interleaved text and images (and video frames) as input and
generates text output, including structured <tool_call> blocks when tools
are supplied.model_type: qwen3_5)step20500 (intermediate)| Property | Value |
|---|---|
| Architecture class | Qwen3_5ForConditionalGeneration |
| Model type | qwen3_5 (text: qwen3_5_text) |
| Hidden size | 2560 |
| Hidden layers | 32 |
| Attention pattern | Hybrid: 3× linear_attention then 1× full_attention (full-attention every 4th layer) |
| Attention heads | 16 (4 KV heads, GQA) |
| Head dim | 256 |
| Linear-attention heads | 16 key / 32 value (key & value head dim 128, conv kernel dim 4) |
| Intermediate size | 9216 (SiLU MLP) |
| Vocab size | 248,320 |
| Max position embeddings | 262,144 (≈262K context) |
| RoPE | mRoPE interleaved, θ = 10,000,000, partial rotary factor 0.25 |
| Tied embeddings | Yes |
| Multi-token prediction | 1 MTP layer |
| Dtype | bfloat16 |
| Vision encoder | 24-layer ViT, hidden 1024, patch size 16, spatial merge 2 → out hidden 2560 |
| Total parameters (weights) | ≈ 9.3 GB on disk across 2 safetensors shards |
Qwen2VLImageProcessorFast,
Qwen3VLProcessor) with image mean/std of 0.5.<tool_call> blocks when tools are provided).| Role | Token |
|---|---|
| EOS | `< |
| Pad | `< |
| Vision start / end | `< |
| Image / video pad | `< |
tools are passed, the chat template injects a system section describing the
available functions and instructs the model to reply using nested XML:<tool_call>
<function=example_function_name>
<parameter=example_parameter_1>
value_1
</parameter>
</function>
</tool_call><tool_call>...</tool_call> with an inner
<function=...>...</function> block.1from transformers import AutoProcessor, AutoModelForImageTextToText
2import torch
3
4model_id = "nvidia/nemotron_edge_exp-steep_jellyfish-tool_calling_sft-qwen3_5_4b_base-step20500"
5
6processor = AutoProcessor.from_pretrained(model_id, trust_remote_code=True)
7model = AutoModelForImageTextToText.from_pretrained(
8 model_id, dtype=torch.bfloat16, device_map="auto", trust_remote_code=True
9)
10
11messages = [{"role": "user", "content": "What is the capital of France?"}]
12prompt = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
13inputs = processor(text=[prompt], return_tensors="pt").to(model.device)
14
15out = model.generate(**inputs, max_new_tokens=256)
16print(processor.batch_decode(out[:, inputs["input_ids"].shape[1]:], skip_special_tokens=True)[0])1tools = [{
2 "type": "function",
3 "function": {
4 "name": "get_weather",
5 "description": "Get the current weather for a city.",
6 "parameters": {
7 "type": "object",
8 "properties": {"city": {"type": "string"}},
9 "required": ["city"],
10 },
11 },
12}]
13
14messages = [{"role": "user", "content": "What's the weather in Paris right now?"}]
15prompt = processor.apply_chat_template(
16 messages, tools=tools, tokenize=False, add_generation_prompt=True
17)generation_config.json so the
model stops correctly at the end of each chat turn out of the box. The chat
template terminates assistant turns with <|im_end|> (token 248046), so the
generation config sets eos_token_id: [248046, 248044] (<|im_end|> and
<|endoftext|>). Without this, a server would keep generating past the end of
the turn.1vllm serve nvidia/nemotron_edge_exp-steep_jellyfish-tool_calling_sft-qwen3_5_4b_base-step20500 \
2 --trust-remote-code \
3 --served-model-name nemotron-edge-jellyfish \
4 --max-model-len 32768POST /v1/chat/completions
and POST /v1/completions:1curl http://localhost:8000/v1/chat/completions \
2 -H "Content-Type: application/json" \
3 -d '{
4 "model": "nemotron-edge-jellyfish",
5 "messages": [{"role": "user", "content": "List three uses for a paperclip."}],
6 "max_tokens": 256
7 }'base_url at the server:1from openai import OpenAI
2
3client = OpenAI(base_url="http://localhost:8000/v1", api_key="EMPTY")
4resp = client.chat.completions.create(
5 model="nemotron-edge-jellyfish",
6 messages=[{"role": "user", "content": "Hello!"}],
7)
8print(resp.choices[0].message.content)image_url content parts, which vLLM
maps onto the model's vision tokens:1curl http://localhost:8000/v1/chat/completions \
2 -H "Content-Type: application/json" \
3 -d '{
4 "model": "nemotron-edge-jellyfish",
5 "messages": [{"role": "user", "content": [
6 {"type": "image_url", "image_url": {"url": "https://example.com/cat.jpg"}},
7 {"type": "text", "text": "Describe this image."}
8 ]}],
9 "max_tokens": 256
10 }'tools field, start the server with auto
tool choice enabled:1vllm serve nvidia/nemotron_edge_exp-steep_jellyfish-tool_calling_sft-qwen3_5_4b_base-step20500 \
2 --trust-remote-code \
3 --served-model-name nemotron-edge-jellyfish \
4 --enable-auto-tool-choice \
5 --tool-call-parser hermesNote: This checkpoint emits a custom XML tool-call format (<tool_call><function=...><parameter=...>...</parameter></function></tool_call>) rather than the JSON Hermes format. The built-in parsers may not parse it perfectly; you can still read the raw<tool_call>blocks from the message content, or supply a matching custom--tool-call-parserplugin. Verify parsing against your prompts before relying on structuredtool_callsoutput.
Version requirement: Theqwen3_5architecture is new. Use a vLLM build recent enough to includeQwen3_5ForConditionalGenerationsupport (install frommainif a released version does not yet recognizemodel_type: qwen3_5).
handler.py implementing the
EndpointHandler interface and a requirements.txt, so it can
be deployed directly as a Custom Inference Endpoint
(see the Inference Toolkit docs).1{
2 "inputs": [
3 {"role": "user", "content": "List three uses for a paperclip."}
4 ],
5 "parameters": {"max_new_tokens": 256, "do_sample": false}
6}1{
2 "inputs": [
3 {"role": "user", "content": [
4 {"type": "image", "image": "https://example.com/cat.jpg"},
5 {"type": "text", "text": "Describe this image."}
6 ]}
7 ],
8 "parameters": {"max_new_tokens": 256}
9}1{
2 "inputs": [{"role": "user", "content": "Weather in Paris?"}],
3 "tools": [
4 {"type": "function", "function": {
5 "name": "get_weather",
6 "description": "Get the current weather for a city.",
7 "parameters": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]}
8 }}
9 ],
10 "parameters": {"max_new_tokens": 256}
11}[{"generated_text": "..."}]Theqwen3_5architecture requires a recent Transformers build (transformers>=4.57.0, or install from source). If model loading fails with an unknownmodel_type: qwen3_5, upgrade Transformers from GitHubmain.
step20500nemotron_edge_exp · steep_jellyfish · tool_calling_sft · qwen3_5_4b_base