Instructions to use amd/tiny-qwen3-moe-w4a8 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use amd/tiny-qwen3-moe-w4a8 with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="amd/tiny-qwen3-moe-w4a8") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("amd/tiny-qwen3-moe-w4a8") model = AutoModelForCausalLM.from_pretrained("amd/tiny-qwen3-moe-w4a8", device_map="auto") messages = [ {"role": "user", "content": "Who are you?"}, ] inputs = tokenizer.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=40) print(tokenizer.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use amd/tiny-qwen3-moe-w4a8 with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "amd/tiny-qwen3-moe-w4a8" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "amd/tiny-qwen3-moe-w4a8", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/amd/tiny-qwen3-moe-w4a8
- SGLang
How to use amd/tiny-qwen3-moe-w4a8 with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "amd/tiny-qwen3-moe-w4a8" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "amd/tiny-qwen3-moe-w4a8", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "amd/tiny-qwen3-moe-w4a8" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "amd/tiny-qwen3-moe-w4a8", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use amd/tiny-qwen3-moe-w4a8 with Docker Model Runner:
docker model run hf.co/amd/tiny-qwen3-moe-w4a8
File size: 5,941 Bytes
f6c2209 0a5677b f6c2209 0a5677b f6c2209 0a5677b f6c2209 0a5677b f6c2209 0a5677b f6c2209 0a5677b f6c2209 0a5677b f6c2209 0a5677b f6c2209 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | ---
library_name: transformers
license: apache-2.0
pipeline_tag: text-generation
tags: [vllm_ci]
---
# Model Overview
- **Model Architecture:** Qwen3MoeForCausalLM (tiny, randomly initialized)
- **Input:** Text
- **Output:** Text
- **Supported Hardware Microarchitecture:** AMD MI300 / MI350 / MI355 (gfx942 / gfx950)
- **Inference Engine:** [vLLM](https://docs.vllm.ai/en/latest/)
- **Model Optimizer:** [AMD-Quark](https://quark.docs.amd.com/latest/index.html)
- **Weight quantization:** W4A8 — INT4 weights (per-channel, symmetric) produced
via a progressive FP8→INT4 spec, following the
[amd/Kimi-K2.5-W4A8](https://huggingface.co/amd/Kimi-K2.5-W4A8) recipe
- **Activation quantization:** FP8 E4M3, per-tensor, dynamic
- **Quantized layers:** routed MoE experts only (attention, router/gate, and
`lm_head` are kept in the original precision)
This is a **tiny, randomly-initialized** Qwen3-MoE model quantized to W4A8, used
purely as **vLLM CI coverage** for the Quark W4A8 fused-MoE path
(`QuarkW4A8Fp8MoEMethod`), which dispatches through the ROCm AITER fused MoE
kernel. It is not intended to produce meaningful text — it exists so CI can load
a real W4A8 checkpoint and run a forward pass on GPU.
The dimensions (hidden `2048`, MoE intermediate `1024`, `8` experts, top-`2`) are
multiples of 256 so the AITER W4A8 shuffle/GEMM tile constraints hold. The
`vocab_size` matches the tokenizer so token ids stay within the embedding table.
# Model Creation
Built and quantized with [AMD-Quark](https://quark.docs.amd.com/latest/index.html),
following the progressive FP8→INT4 weight spec from the
[amd/Kimi-K2.5-W4A8](https://huggingface.co/amd/Kimi-K2.5-W4A8) model card.
> Note: Quark quantizes `nn.Linear` modules. MoE experts are stored as individual
> `nn.Linear` layers in `transformers` ~4.57; quantize with that version so the
> routed experts are captured.
```python
import argparse
import torch
from datasets import load_dataset
from torch.utils.data import DataLoader
from transformers import AutoConfig, AutoModelForCausalLM, AutoTokenizer
from quark.torch import ModelQuantizer, export_safetensors
from quark.torch.quantization.config.config import (
FP8E4M3PerTensorSpec,
Int4PerChannelSpec,
ProgressiveSpec,
QConfig,
QLayerConfig,
)
def get_config() -> QConfig:
# Quantize the routed experts only.
exclude_layers = ["*self_attn*", "*mlp.gate", "*lm_head"]
input_spec = FP8E4M3PerTensorSpec(
observer_method="min_max", scale_type="float", is_dynamic=True
).to_quantization_spec()
# Progressive FP8 -> INT4 weight spec (Kimi-K2.5-W4A8 recipe).
weight_spec = ProgressiveSpec(
first_stage=FP8E4M3PerTensorSpec(
observer_method="min_max", scale_type="float", is_dynamic=False
),
second_stage=Int4PerChannelSpec(
symmetric=True,
scale_type="float",
round_method="half_even",
is_dynamic=False,
ch_axis=0,
),
).to_quantization_spec()
return QConfig(
global_quant_config=QLayerConfig(input_tensors=input_spec, weight=weight_spec),
exclude=exclude_layers,
)
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument("--export-path", required=True)
parser.add_argument("--tokenizer", default="Qwen/Qwen1.5-MoE-A2.7B-Chat")
parser.add_argument("--hidden", type=int, default=2048)
parser.add_argument("--moe-intermediate", type=int, default=1024)
parser.add_argument("--experts", type=int, default=8)
parser.add_argument("--topk", type=int, default=2)
parser.add_argument("--layers", type=int, default=2)
parser.add_argument("--seed", type=int, default=0)
args = parser.parse_args()
torch.manual_seed(args.seed)
tokenizer = AutoTokenizer.from_pretrained(args.tokenizer)
# vocab_size MUST cover the tokenizer, else real prompts produce token ids
# beyond the embedding table -> out-of-bounds embedding lookup (GPU fault).
cfg = AutoConfig.for_model(
"qwen3_moe",
hidden_size=args.hidden,
intermediate_size=args.hidden,
moe_intermediate_size=args.moe_intermediate,
num_hidden_layers=args.layers,
num_attention_heads=16,
num_key_value_heads=2,
head_dim=128,
num_experts=args.experts,
num_experts_per_tok=args.topk,
vocab_size=len(tokenizer),
max_position_embeddings=2048,
)
model = AutoModelForCausalLM.from_config(cfg).to("cuda").eval().to(torch.bfloat16)
ds = load_dataset("mit-han-lab/pile-val-backup", split="validation")
samples = [
tokenizer(ds[i]["text"], return_tensors="pt", truncation=True,
max_length=64).input_ids.to("cuda")
for i in range(8)
]
dataloader = DataLoader(samples, batch_size=1)
quantizer = ModelQuantizer(get_config())
with torch.no_grad():
model = quantizer.quantize_model(model, dataloader)
export_safetensors(
model, args.export_path, custom_mode="quark",
weight_format="real_quantized", pack_method="reorder",
)
tokenizer.save_pretrained(args.export_path)
# Symmetric INT4 export emits all-zero `*_zero_point_2` tensors that vLLM's
# W4A8 loader does not expect; drop them so the checkpoint loads directly.
if __name__ == "__main__":
main()
```
# Usage in vLLM
W4A8 dispatches through the ROCm AITER fused MoE kernel, so run on gfx942/gfx950
with AITER enabled:
```bash
VLLM_ROCM_USE_AITER=1 VLLM_ROCM_USE_AITER_MOE=1 \
vllm serve amd/tiny-qwen3-moe-w4a8 --enforce-eager
```
Because the weights are random, outputs are not meaningful — this model is a
structural / smoke-test fixture only.
# License
Apache-2.0. The tiny model is randomly initialized and derives no weights from
any base model.
Modifications Copyright(c) 2026 Advanced Micro Devices, Inc. All rights reserved.
|