Quantization details
- Scheme — W4A4 — FP4 (E2M1) weights group 16 (FP8 E4M3 scale + per-tensor FP32 global scale), FP4 activations, stored as compressed-tensors
nvfp4-pack-quantized.
- Kept in BF16 — the vision tower & projector (
model.visual.*), the multi-token-prediction head (mtp.*), all RMSNorms, token embeddings, the LM head, the entire linear-attention (GatedDeltaNet/SSM) path — FP4 is too coarse for the SSM weights, so the full linear_attn.* stays BF16. Left unquantized to preserve quality (about 55% of all parameters in this build).
- Tokenizer /
chat_template / generation_config are identical to the original. config.json is the original plus a quantization_config block.
This is post-training quantization (PTQ) — no retraining. AWQ uses a small calibration set (no gradient) to protect salient weight channels before rounding.
Benchmarks (measured)
Every column was measured with the same harness and settings — lm-evaluation-harness on vLLM, greedy, few-shot completion (no chat template). Percentages are recovery vs. the BF16 original.
Table with columns: Benchmark, BF16 (original), FP8-dynamic, AWQ-8bit, NVFP4A16, NVFP4 (this repo), AWQ-4bit| Benchmark | BF16 (original) | FP8-dynamic | AWQ-8bit | NVFP4A16 | NVFP4 (this repo) | AWQ-4bit |
|---|
| MMLU (5-shot) | 53.33 | 48.18 (90.3%) | 53.54 (100.4%) | 54.27 (101.8%) | 55.22 (103.5%) | 60.38 (113.2%) |
| GSM8K (5-shot, strict) | 58.23 | 56.63 (97.3%) | 56.56 (97.1%) | 54.51 (93.6%) | 51.71 (88.8%) | 54.06 (92.8%) |
| ARC-Challenge (0-shot) | 41.47 | 41.98 (101.2%) | 41.30 (99.6%) | 41.04 (99.0%) | 39.51 (95.3%) | 39.59 (95.5%) |
| Winogrande (5-shot) | 64.56 | 63.22 (97.9%) | 64.48 (99.9%) | 64.48 (99.9%) | 61.09 (94.6%) | 62.51 (96.8%) |
| KMMLU (5-shot, direct) | 43.29 | 42.58 (98.4%) | 43.20 (99.8%) | 42.01 (97.1%) | 41.14 (95.0%) | 42.10 (97.3%) |
| HAE-RAE (0-shot) | 45.65 | 45.00 (98.6%) | 45.10 (98.8%) | 44.91 (98.4%) | 42.07 (92.2%) | 41.06 (90.0%) |
| Average | 51.09 | 49.60 (97.1%) | 50.70 (99.2%) | 50.21 (98.3%) | 48.46 (94.8%) | 49.95 (97.8%) |
⚠️ Note: average recovery is 94.8% — noticeable degradation at this precision; prefer an 8-bit build if quality matters most.
Evaluation (measured)
Fidelity to the BF16 original on an internal mixed English/Korean set (100 prompts, BF16 greedy answers scored under each build — same harness for every row).
Table with columns: Metric, This model, BF16 original| Metric | This model | BF16 original |
|---|
| Perplexity (lower = closer) | 2.0399 | 1.8515 (+10.2%) |
| Top-1 next-token agreement | 85.8% | 98.9% |
These measure fidelity to the base model, not absolute task scores.
⚠️ Note: this small dense model is sensitive to 4-bit quantization (+10.2% perplexity here). For production we recommend the 8-bit builds (FP8 or AWQ INT8) of this model.
Requirements
Table | |
|---|
| Runtime | vLLM — the architecture is in vLLM ≥ 0.17.0; tested here with vLLM 0.32.0. |
| vLLM install | vLLM 0.32 itself needs Python 3.11–3.14, torch 2.13 (CUDA 13.0 build, so an NVIDIA driver with CUDA 13 support), transformers ≥5.16.1,<5.20 and compressed-tensors 0.17.0 (both pinned by vLLM; 0.17.0 reads this checkpoint, which was saved with 0.19.0 — do not upgrade it separately). |
| GPU | Full FP4 (W4A4) speed on Blackwell — B200/GB200 (sm100), B300 (sm103), RTX 50xx / RTX PRO 6000 (sm120). Turing–Hopper (sm75–90) fall back to weight-only FP4 (slower, vLLM warns). V100 (sm70) is not supported. (Kernel choice per GPU from vLLM 0.32's selection code; only B200 was run here.) |
| Memory | Weights: 3.1 GB. Add KV cache (grows with context length × concurrent requests) and a few GB for activations / CUDA graphs; use --tensor-parallel-size N when the weights do not fit one GPU. |
| Transformers (without vLLM) | transformers>=5.2.0 + compressed-tensors>=0.15.0 (checked on CPU with Qwen3.5-0.8B FP8 / AWQ-4bit / NVFP4A16 / NVFP4). |
| trust_remote_code | not needed |
Usage (vLLM)
Start an OpenAI-compatible server:
vllm serve axteam/Qwen3.5-2B-NVFP4 --max-model-len 32768
Query it:
curl http://localhost:8000/v1/chat/completions -H "Content-Type: application/json" -d '{ "model": "axteam/Qwen3.5-2B-NVFP4", "messages": [{"role": "user", "content": "대한민국의 수도는 어디인가요?"}], "max_tokens": 512}'
Offline inference in Python:
from vllm import LLM, SamplingParams llm = LLM(model="axteam/Qwen3.5-2B-NVFP4", max_model_len=32768)params = SamplingParams(max_tokens=1024)out = llm.chat([{"role": "user", "content": "Explain model quantization in two sentences."}], params)print(out[0].outputs[0].text) # image input (URL or data: URI)messages = [{"role": "user", "content": [ {"type": "image_url", "image_url": {"url": "https://example.com/your-image.png"}}, {"type": "text", "text": "Describe this image."},]}]out = llm.chat(messages, params)print(out[0].outputs[0].text)
Thinking mode is off by default in this model's chat template; to turn it on pass chat_template_kwargs={"enable_thinking": True} (Python llm.chat(..., chat_template_kwargs=...), or "chat_template_kwargs": {"enable_thinking": true} in the request body).
Text-only serving: add --limit-mm-per-prompt '{"image": 0, "video": 0}' to skip loading the vision encoder's memory budget.
Reducing KV-cache memory (optional, serve-time)
The KV cache is kept in BF16 by default. KV-cache precision is a runtime choice, independent of the
weight quantization above; for long contexts or large batches FP8 roughly halves KV-cache memory:
vllm serve axteam/Qwen3.5-2B-NVFP4 --kv-cache-dtype fp8
License
Quantized derivative of Qwen/Qwen3.5-2B (Apache-2.0). All original weights, tokenizer and chat template belong to the Qwen team.
한국어 요약
Qwen/Qwen3.5-2B의 NVFP4 (W4A4) 양자화 빌드 · 제작 axteam
개요
Table with columns: 항목, 내용| 항목 | 내용 |
|---|
| 원본 모델 | Qwen/Qwen3.5-2B |
| 양자화 방식 | NVFP4 (W4A4, 가중치·활성화 FP4) |
| 저장 형식 | compressed-tensors nvfp4-pack-quantized |
| 모델 구조 | 하이브리드 어텐션(선형 어텐션 + 풀 어텐션) · Dense · 멀티모달(비전) · MTP 헤드 |
| 용량 | 약 3.1 GB |
| 보정 데이터 | 샘플 256개 (한국어 위주 혼합 코퍼스) |
양자화 상세
- 가중치: FP4(E2M1), 그룹 크기 16 (그룹별 FP8(E4M3) 스케일 + 텐서별 FP32 전역 스케일)
- 활성화: 실행 시 FP4 (Blackwell FP4 텐서코어에서 가속)
- 양자화 절차: PTQ(학습 후 양자화, 재학습 없음), AWQ 방식 — 보정 데이터로 활성화가 큰 가중치 채널을 찾아 채널별 스케일로 보호한 뒤 FP4로 반올림
- BF16 유지: 비전 타워·투영층(
model.visual.*), MTP 헤드(mtp.*), 모든 RMSNorm, 토큰 임베딩, LM 헤드, 선형 어텐션(GatedDeltaNet/SSM) 경로 전체(linear_attn.*, FP4로는 정밀도 부족) — 전체 파라미터의 약 55%
- 원본 파일: 토크나이저·chat template·generation config는 원본과 동일,
config.json은 원본에 quantization_config 블록만 추가
품질 (실측)
- 원본 대비 충실도: PPL 2.0399 (원본 1.8515, +10.2%, 낮을수록 원본에 가까움), 다음 토큰 top-1 일치율 85.8% (원본 자체 기준값 98.9%) — 내부 영어·한국어 혼합 프롬프트 100개, 원본(BF16)의 greedy 답변을 기준 텍스트로 측정
- 벤치마크 평균: 48.46 (원본 51.09, 94.8%) — MMLU·GSM8K·ARC-Challenge·Winogrande·KMMLU·HAE-RAE 6종 평균, lm-evaluation-harness + vLLM, chat template 없는 few-shot·greedy, 모든 빌드를 같은 설정으로 측정
- 한국어 벤치마크: KMMLU 41.14 (원본 43.29, 95.0%) · HAE-RAE 42.07 (원본 45.65, 92.2%)
- 주의: ⚠️ 이 정밀도에서 품질 저하가 뚜렷함 (PPL +10.2%, 벤치마크 평균 원본 대비 94.8%) — 품질이 중요하면 8비트(FP8·AWQ-8bit) 빌드 권장
요구사항
- 실행 엔진: vLLM 0.17.0 이상(이 구조를 지원하는 첫 버전), 이 빌드는 vLLM 0.32.0에서 실행 확인
- vLLM 0.32 설치 조건: Python 3.11~3.14, torch 2.13(CUDA 13.0 빌드, CUDA 13 지원 드라이버 필요), transformers 5.16.1 이상 5.20 미만, compressed-tensors 0.17.0 — transformers·compressed-tensors는 vLLM이 버전을 고정하므로 compressed-tensors를 따로 업그레이드하지 말 것 (이 체크포인트는 0.19.0으로 저장됐지만 0.17.0에서도 로드됨)
- GPU: Blackwell(B200·GB200 sm100, B300 sm103, RTX 50xx·RTX PRO 6000 sm120)에서 FP4(W4A4) 연산 가속, V100(sm70) 미지원 — Turing
Hopper(sm7590)는 가중치 전용 FP4로 자동 전환되어 속도 저하, vLLM 경고 출력 (GPU별 지원 여부는 vLLM 0.32 커널 선택 코드 기준, 실제 실행은 B200에서만 확인)
- 메모리: 가중치 3.1 GB + KV 캐시(컨텍스트 길이 × 동시 요청 수에 비례) + 활성화·CUDA graph용 수 GB — GPU 한 장에 다 들어가지 않으면
--tensor-parallel-size N으로 분산
- Transformers로 직접 사용: transformers 5.2.0 이상 + compressed-tensors 0.15.0 이상 (Qwen3.5-0.8B의 FP8·AWQ-4bit·NVFP4A16·NVFP4 빌드로 CPU에서 확인)
- trust_remote_code: 불필요
사용법
- 서버 실행:
vllm serve axteam/Qwen3.5-2B-NVFP4 --max-model-len 32768 — OpenAI 호환 API
- Python:
LLM(model="axteam/Qwen3.5-2B-NVFP4", max_model_len=32768).chat(...) — 전체 예시는 위 영어 본문 'Usage (vLLM)' 절 참고
- thinking 모드: 기본 꺼짐 — 켜려면
chat_template_kwargs={"enable_thinking": True} 전달(Python은 llm.chat() 인자, HTTP는 요청 본문의 "chat_template_kwargs": {"enable_thinking": true})
- 이미지 입력: 메시지에
image_url 항목 사용
- 텍스트만 사용할 때:
--limit-mm-per-prompt '{"image": 0, "video": 0}' — 비전 타워용 메모리 예약을 생략해 메모리 절약
- KV 캐시 절감(선택):
vllm serve에 --kv-cache-dtype fp8 추가 — 기본 BF16인 KV 캐시를 FP8로 저장해 KV 캐시 메모리를 약 절반으로 줄임 (긴 컨텍스트·동시 요청이 많을 때 유리, 가중치 양자화와 별개인 실행 옵션)
참고
- 수정 이력 (2026-11-01): AWQ가 스무딩하지 않는 RMSNorm 가중치를 원본과 비트 단위로 같게 복원 — llm-compressor가 남긴 BF16 반올림 오차(실효 가중치 기준 최대 0.4%) 제거, 양자화 가중치와 AWQ로 스무딩된 RMSNorm은 변경 없음, 품질 항목의 측정값은 복원 전 기준
라이선스
- 라이선스: Apache-2.0 — 원본 모델의 라이선스를 그대로 따름
- 권리: 원본 가중치·토크나이저·chat template은 Qwen 팀(Alibaba) 소유, 이 리포는 양자화 파생물