Ascend에서의 양자화
Ascend에서의 양자화 (Quantization on Ascend)
이미 양자화된 모델을 불러올 때는 모델 가중치와 config를 그대로 로드하면 돼요. 오프라인으로 양자화된 모델이라면 엔진 시작 시 --quantization 인자를 추가할 필요가 없어요. 양자화 방식은 다운로드한 quant_model_description.json 또는 config.json config에서 자동으로 파싱돼요.
출처: 문서
본문
SGLang은 mix-bits 양자화를 지원해요(quant_model_description.json에 지정된 양자화 유형에 따라 각 레이어를 독립적으로 정의하고 로드해요). MoE용 고급 mix-bits는 진행 중이며, w13(up-gate)과 w2(down) 레이어에 대한 독립적인 양자화 결정을 추가할 예정이에요.
| 양자화 방식 | 레이어 유형 | A2 Series 지원 | A3 Series 지원 | 950PR/DT Series 지원 | Diffusion 모델 |
|---|---|---|---|---|---|
| W4A4 dynamic | Linear | √ | √ | TBD | √ |
| W8A8 static | Linear | √ | √ | TBD | √ |
| W8A8 dynamic | Linear | √ | √ | TBD | √ |
| MXFP8 (Diffusion, LLM dense) | Linear | x | x | √ | √ |
| MXFP4 | Linear | x | x | √ | √ |
| MXFP4 W4A8 | Linear | x | x | √ | x |
| MXFP4 W4A8 (ModelSlim) | MoE | x | x | √ | x |
| MXFP4 W4A4 | Linear | x | x | WIP | x |
| MXFP4 W4A4 (ModelSlim) | MoE | x | x | √ | x |
| W4A4 dynamic | MoE | √ | √ | TBD | x |
| W4A8 dynamic | MoE | √ | √ | TBD | x |
| W8A8 dynamic | MoE | √ | √ | TBD | x |
| MXFP8 (LLM MoE) | MoE | x | x | √ | x |
| 양자화 방식 | 레이어 유형 | A2 Series 지원 | A3 Series 지원 | 950PR/DT Series 지원 |
|---|---|---|---|---|
| W4A16 | Linear | √ | √ | TBD |
| W8A16 | Linear | √ | √ | TBD |
| W4A16 | MoE | √ | √ | TBD |
Ascend에서의 GPTQ 지원
| 양자화 방식 | 레이어 유형 | A2 Series 지원 | A3 Series 지원 | 950PR/DT Series 지원 |
|---|---|---|---|---|
| W4A16 | Linear | √ | √ | TBD |
| W8A16 | Linear | √ | √ | TBD |
| W4A16 MOE | MoE | √ | √ | TBD |
| W8A16 MOE | MoE | √ | √ | TBD |
| 양자화 방식 | 레이어 유형 | A2 Series 지원 | A3 Series 지원 | 950PR/DT Series 지원 |
|---|---|---|---|---|
| W4A16 | Linear | √ | √ | TBD |
| W8A16 | Linear | √ | √ | TBD |
| W4A16 | MoE | √ | √ | TBD |
| W8A16 | MoE | √ | √ | TBD |
Ascend에서의 Compressed-tensors (LLM Compressor) 지원:
| 양자화 방식 | 레이어 유형 | A2 Series 지원 | A3 Series 지원 | 950PR/DT Series 지원 |
|---|---|---|---|---|
| W8A8 dynamic | Linear | √ | √ | TBD |
| activations clip 유/무 W4A8 dynamic | MoE | √ | √ | TBD |
| W4A16 MOE | MoE | √ | √ | TBD |
| W8A8 dynamic | MoE | √ | √ | TBD |
| 양자화 유형 | 레이어 유형 | A2 Series 지원 | A3 Series 지원 | 950PR/DT Series 지원 |
|---|---|---|---|---|
| 모든 GGUF 유형 (standard, K-quant) | Linear | √ | √ | TBD |
| 모든 GGUF 유형 (standard, K-quant) | MoE | √ | √ | TBD |
사용 예시:
- Dense 모델 (예: Qwen3-14B-Q4_K_M.gguf):
python3 -m sglang.launch_server \
--model-path Qwen3-14B-Q4_K_M.gguf \
--device npu --attention-backend ascend \
--host 0.0.0.0 --port 30000 \
--mem-fraction-static 0.7 --tp-size 2
- MoE 모델 (예: Qwen3-30B-A3B-Q4_K_M.gguf):
python3 -m sglang.launch_server \
--model-path Qwen3-30B-A3B-Q4_K_M.gguf \
--device npu --attention-backend ascend \
--host 0.0.0.0 --port 30000 \
--mem-fraction-static 0.8 --tp-size 2
구현 참고 사항:
- GGUF 가중치는 모델 로딩 시 CPU에서 FP16/BF16으로 미리 역양자화된 후 추론을 위해 NPU로 전송돼요. 이는 더 높은 메모리 사용량과 더 빠른 런타임 성능(순방향 패스당 역양자화 오버헤드 없음)의 트레이드오프를 만들어요.
- MoE 레이어는
npu_grouped_matmul과npu_moe_init_routing/npu_moe_finalize_routing을 사용해 고성능 전문가 계산을 수행해요.- TP(tensor parallelism) 샤딩은 dense와 MoE GGUF 모델 모두 지원돼요.
LLM dense 모델용 MXFP8 (예: Qwen3 / Qwen3.5):
LLM dense W8A8 MXFP8 Linear 지원은 PR #22352에서 Ascend에 추가됐어요. Ascend 950PR/DT Series 이상이 필요해요(npu_dynamic_mx_quant는 A2/A3 Series에서 사용할 수 없어요).
- 온라인 MXFP8 양자화 (BF16/FP16 가중치 → 로드 시 MXFP8):
python3 -m sglang.launch_server \
--model-path Qwen/Qwen3-8B \
--quantization mxfp8 \
--device npu --attention-backend ascend \
--host 0.0.0.0 --port 30000 \
--mem-fraction-static 0.8 --tp-size 1
- 오프라인 MXFP8 양자화 (msmodelslim 사전 양자화 가중치,
W8A8_MXFP8방식;--quantization플래그 불필요 —quant_model_description.json에서 자동 감지):
python3 -m sglang.launch_server \
--model-path /path/to/Qwen3-8B-W8A8-MXFP8 \
--device npu --attention-backend ascend \
--host 0.0.0.0 --port 30000 \
--mem-fraction-static 0.8 --tp-size 1
구현 참고 사항:
- 온라인 경로:
Fp8Config.get_quant_method()가NPUMXFP8LinearMethod로 디스패치해요. 가중치는 로드 시npu_dynamic_mx_quant(weight, dst_type=torch_npu.float8_e4m3fn)으로 한 번 양자화되고[in, out]으로 미리 전치돼요. 활성화는 추론 시 토큰별로 양자화되고 matmul은npu_quant_matmul(..., group_sizes=[1, 1, 32])(block_size = 32)로 실행돼요.- 오프라인 경로:
ModelSlimMXFP8Scheme이 msmodelslim이 사전 내보낸float8_e4m3fn가중치와float8_e8m0fnu블록 스케일을 로드해요. 전치는 비연속(non-contiguous) 뷰로 유지돼요(.data할당) —.contiguous()를 호출하면 사전 양자화된 레이아웃을 물리적으로 재배열해 블록 스케일 매핑을 깨뜨려요.- LLM용 MoE MXFP8 (FusedMoE)은 아래 LLM MoE 모델용 MXFP8 에 문서화되어 있어요.
LLM MoE 모델용 MXFP8 (예: Qwen3-30B-A3B / Qwen3.5 MoE):
LLM MoE W8A8 MXFP8 (FusedMoE) 지원은 dense MXFP8 경로를 기반으로 해요. Ascend 950PR/DT Series 이상이 필요해요 — 통합 MoE MX 커널(npu_grouped_matmul_swiglu_quant_v2, npu_dynamic_mx_quant)은 950PR/DT Series에서만 사용할 수 있어요.
- 온라인 MXFP8 양자화 (BF16/FP16 전문가 가중치 → 로드 시 MXFP8):
python3 -m sglang.launch_server \
--model-path Qwen/Qwen3-30B-A3B \
--quantization mxfp8 \
--device npu --attention-backend ascend \
--host 0.0.0.0 --port 30000 \
--mem-fraction-static 0.8 --tp-size 1
- 오프라인 MXFP8 양자화 (msmodelslim 사전 양자화 가중치,
W8A8_MXFP8방식).--quantization플래그가 필요 없어요: 체크포인트에 포함된quant_model_description.json이 ModelSlim 경로와 방식을 모두 자동으로 선택해요.
python3 -m sglang.launch_server \
--model-path /path/to/Qwen3-30B-A3B-W8A8-MXFP8 \
--device npu --attention-backend ascend \
--host 0.0.0.0 --port 30000 \
--mem-fraction-static 0.8 --tp-size 1
구현 참고 사항:
- 두 경로 모두 공유 per-gmm 커널
NPUMXFP8MoEMethod(hardware_backend/npu/quantization/moe_methods.py)를 사용하며, 가중치 dtype으로 온라인/오프라인을 구분해요. 전문가 가중치와 그 e8m0 블록 스케일은 비연속 전치 뷰로 유지돼요 —.contiguous()를 호출하면 HBM 대역폭을 낭비하게 돼요.- 온라인 경로:
Fp8Config.get_quant_method()가 FusedMoE 레이어를NPUMXFP8OnlineMoEMethod로 디스패치해요. 이는UnquantizedFusedMoEMethod를 상속하고create_moe_runner만 오버라이드해 MXFP8 커널을 교체해요 — 가중치 생성, 가중치 후처리, 순방향 패스는 모두 unquantized Ascend 경로를 그대로 써요. BF16 전문가 가중치w13/w2는 로드 시npu_dynamic_mx_quant(dst_type=torch.float8_e4m3fn)으로 한 번 양자화돼요(3D[E, N, K]입력을 직접 받아요).- 오프라인 경로:
ModelSlimMXFP8MoEScheme(가중치 그룹당 인스턴스 하나)이float8_e4m3fn전문가 가중치와 uint8(e8m0, 지수 + 127) 블록 스케일을 로드해요. 스케일은[E, N, K/32] → [E, N, K/64, 2]로 reshape된 후(연속 페어링,npu_dynamic_mx_quant와 일치) 전치돼요.- 순방향:
AscendTPDispatcher가npu_moe_init_routing_v2(quant_mode=3)을 실행하며, 이는 토큰별 MX 활성화 양자화를 라우팅에 통합해요(e4m3 페이로드 + e8m0 블록 스케일, 페어 분할 레이아웃으로 reshape).AscendRunnerCore는 gmm1npu_grouped_matmul_swiglu_quant_v2(누적group_list; gate/up + swiglu + requant를 통합해 별도의 활성화 단계가 없어요) → gmm2npu_grouped_matmul(countgroup_list)을 실행해요. UE8M0(float8_e8m0fnu) 스케일 dtype은 명시적으로 전달되고 e4m3x/weightdtype은 암시적으로 남겨져요.- 라우터 게이트: msmodelslim은
mlp.gate도 양자화할 수 있어요(W8A8_MXFP8). 게이트는ReplicatedLinear이므로 그 양자화는 설명 기반이어야 해요: 오프라인modelslim경로에서는 게이트에 양자 구성이 전달되어 올바르게 역양자화되지만, 온라인 경로는 BF16으로 유지해요. 양자화된 게이트를 블록 스케일 없이 BF16으로 로드하면 라우팅이 망가지고 쓰레기 출력이 생성돼요.- 활성화 양자화 위치는 디스패처에 따라 달라져요.
ascend_tp에서는 위 설명처럼 라우팅에 통합돼요. DeepEP에는 MXFP8 디스패치 dtype이 없어서 BF16으로 디스패치를 유지하고 gmm1이 fused 커널 전에npu_dynamic_mx_quant로 hidden states를 자체 양자화해요 — 두 경로가 같은 gmm1 입력에 도달해요.ascend_tp경로만 Ascend 950PR/DT Series에서 엔드투엔드로 검증됐어요.
LLM dense 모델용 MXFP4 W4A8 (예: Qwen3 / Qwen3.5):
LLM dense W4A8 (MXFP4 4비트 가중치 + MXFP8 8비트 활성화) Linear 지원은 PR #23650에서 추가됐어요. Ascend 950PR/DT Series 이상이 필요해요.
- 온라인 W4A8 양자화 (BF16/FP16 가중치 → 로드 시 MXFP4):
python3 -m sglang.launch_server \
--model-path Qwen/Qwen3-8B \
--quantization mxfp_w4a8 \
--device npu --attention-backend ascend \
--host 0.0.0.0 --port 30000 \
--mem-fraction-static 0.8 --tp-size 1
- 오프라인 W4A8 양자화 (msmodelslim 사전 양자화 가중치,
W4A8_MXFP방식;--quantization플래그 불필요 —quant_model_description.json에서 자동 감지).
구현 참고 사항:
- 가중치는 FP4(
float4_e2m1fn_x2, 바이트당 2 니블)로 패킹되고 UE8M0 per-block 공유 지수(block_size = 32)를 가지며, 활성화는 토큰별 MXFP8이에요. matmul은npu_quant_matmul(..., x2_dtype=torch_npu.float4_e2m1fn_x2, group_sizes=[0, 0, 32])로 실행돼요.- NPU 연산자에 전달되는 packed-FP4 dtype(
dst_type/x2_dtype/input_dtype)은torch_npu.float4_e2m1fn_x2(int enum)에서 해석해야 해요. 최신 op-plugin 빌드는torch.float4_e2m1fn_x2dtype 객체를 거부해요.- 온라인과 오프라인은 같은 커널 경로와 레이아웃을 공유해요. 가중치 소스(로드 시 RTN vs msmodelslim 캘리브레이션)만 다를 뿐이에요.
LLM MoE 모델용 ModelSlim W4A8 MXFP4:
SGLang은 quant_model_description.json에서 오프라인 ModelSlim W4A8_MXFP MoE 체크포인트를 자동 감지해요. --quantization을 전달하지 마세요. 이 경로는 Ascend 950PR/DT Series 이상이 필요해요.
MODEL_PATH=/path/to/w4a8-mxfp4-moe-model
python3 -m sglang.launch_server \
--model-path "$MODEL_PATH" \
--device npu --attention-backend ascend \
--host 0.0.0.0 --port 30000 \
--tp-size 1
구현 참고 사항:
- ModelSlim은 UE8M0 블록 스케일(블록 크기 32)을 가진 packed MXFP4
w13과w2전문가 가중치를 제공해요.- Ascend TP와 DeepEP는 활성화를 BF16으로 디스패치해요. 이 경로는 MXFP8 디스패치를 요청하지 않아요. SGLang은 grouped matmul 직전에 각 전문가 입력을 MXFP8으로 동적으로 양자화해요.
LLM dense 모델용 MXFP4 W4A4 (예: Qwen3 / Qwen3.5):
LLM dense W4A4 (MXFP4 4비트 가중치 + 4비트 활성화) Linear 지원은 PR #23795에서 추가됐어요. Ascend 950PR/DT Series 이상이 필요해요 — 이중 레벨 온라인 경로는 DualLevelQuantBatchMatmul 연산자를 사용하는데, A2/A3 Series에는 없어요. Ascend NPU 백엔드에서 --quantization mxfp4는 이 W4A4 경로를 선택해요(GPU에서는 같은 플래그가 상류 OCP MXFP4 MoE 구성을 대신 선택해요).
- 온라인 W4A4 양자화 (BF16/FP16 가중치 → 로드 시 이중 레벨 MXFP4):
python3 -m sglang.launch_server \
--model-path Qwen/Qwen3-8B \
--quantization mxfp4 \
--device npu --attention-backend ascend \
--host 0.0.0.0 --port 30000 \
--mem-fraction-static 0.8 --tp-size 1
- 오프라인 W4A4 양자화 (msmodelslim 사전 양자화 가중치,
W4A4_MXFP4방식;--quantization플래그 불필요 —quant_model_description.json에서 자동 감지).
구현 참고 사항:
- 온라인 (
NPUDualLevelMXFP4LinearMethod)은 이중 레벨 MXFP4를 사용해요: 가중치와 활성화 모두npu_dynamic_dual_level_mx_quant로 세밀한 FP8(E4M3) L0 블록 스케일과 더 거친 L1 스케일로 양자화되고, matmul은npu_dual_level_quant_matmul(가중치는 FRACTAL_NZ)로 실행돼요. 이중 레벨은 단일 UE8M0(2의 거듭제곱) 스케일보다 블록별 동적 범위를 훨씬 잘 포착해요. 이것이 초기 단일 레벨 RTN 온라인 경로가 성능이 나빴던 이유예요(탐욕 디코딩이 EOS를 내보내지 못하고 루프에 빠질 수 있었어요).- 오프라인 (
ModelSlimMXFP4Scheme→NPUSingleLevelMXFP4OfflineLinearMethod)은 단일 레벨이에요: msmodelslim의W4A4_MXFP4체크포인트는 단일 레벨 UE8M0 블록 스케일(block_size = 32)을 제공하므로 matmul은npu_quant_matmul(..., x1_dtype=x2_dtype=torch_npu.float4_e2m1fn_x2, group_sizes=[1, 1, 32])로 실행돼요. 따라서 온라인과 오프라인 경로는 서로 다른 matmul 커널을 사용해요 — 더 이상 matmul 경로를 공유하지 않아요.- W4A8과 마찬가지로, NPU 연산자에 전달되는 packed-FP4 dtype(
dst_type/x2_dtype)은torch_npu.float4_e2m1fn_x2(int enum)에서 해석해야 해요. 최신 op-plugin 빌드는torch.float4_e2m1fn_x2dtype 객체를 거부해요.- Ascend 950PR/DT Series 하드웨어에서 엔드투엔드로 검증됐어요.
LLM MoE 모델용 ModelSlim W4A4 MXFP4:
SGLang은 quant_model_description.json에서 오프라인 ModelSlim W4A4_MXFP4 MoE 체크포인트를 자동 감지해요. --quantization을 전달하지 마세요. 이 경로는 Ascend 950PR/DT Series 이상이 필요해요.
MODEL_PATH=/path/to/w4a4-mxfp4-moe-model
python3 -m sglang.launch_server \
--model-path "$MODEL_PATH" \
--device npu --attention-backend ascend \
--host 0.0.0.0 --port 30000 \
--tp-size 1
구현 참고 사항:
- ModelSlim은 UE8M0 블록 스케일(블록 크기 32)을 가진 packed MXFP4
w13과w2전문가 가중치를 제공해요.- Ascend TP와 DeepEP는 활성화를 BF16으로 디스패치해요. 이 경로는 MXFP4 디스패치를 요청하지 않아요. SGLang은 grouped matmul 직전에 각 전문가 입력을 MXFP4로 동적으로 양자화해요.
Ascend NPU에서의 Diffusion 모델 양자화 (Diffusion Model Quantization on Ascend NPU)
SGLang-Diffusion은 Ascend NPU에서 diffusion 모델(예: Wan2.2)의 MXFP8 온라인/오프라인 양자화를 지원해요. MXFP8은 Ascend 950PR/DT Series가 필요하고, ModelSlim W8A8/W4A4 방식은 A2/A3 Series에서 동작해요.
MXFP8 요구 사항: CANN ≥ 8.0.RC3, Ascend 950PR/DT Series
| 양자화 방법 | JSON의 quant\_type |
방식 클래스 | 모드 | A2/A3 Series 지원 | 950PR/DT Series 지원 | 트리거 |
|---|---|---|---|---|---|---|
| MXFP8 (W8A8) | — | MXFP8Config |
온라인 | x | √ | --quantization mxfp8 |
| MXFP8 (W8A8) | W8A8\_MXFP8 |
ModelSlimMXFP8Scheme |
오프라인 | x | √ | quant\_model\_description.json에서 자동 감지 |
| W8A8 static | W8A8 |
ModelSlimW8A8Int8 |
오프라인 | √ | TBD | quant\_model\_description.json에서 자동 감지 |
| W8A8 dynamic | W8A8\_DYNAMIC |
ModelSlimW8A8Int8 |
오프라인 | √ | TBD | quant\_model\_description.json에서 자동 감지 |
| W4A4 dynamic | W4A4\_DYNAMIC |
ModelSlimW4A4Int4 |
오프라인 | √ | TBD | quant\_model\_description.json에서 자동 감지 |
온라인 MXFP8 양자화 (Online MXFP8 Quantization)
온라인 양자화는 로드 시 npu_dynamic_mx_quant + npu_quant_matmul CANN 커널을 사용해 FP16/BF16 가중치를 MXFP8로 동적으로 양자화해요. 자동 감지를 재정의하려면 --quantization mxfp8을 전달하세요.
# 온라인 MXFP8 양자화로 diffusion 서버 시작
sglang serve \
--model-path Wan-AI/Wan2.2-T2V-A14B-Diffusers \
--quantization mxfp8 \
--num-gpus 4
# 원샷 생성
sglang generate \
--model-path Wan-AI/Wan2.2-T2V-A14B-Diffusers \
--quantization mxfp8 \
--prompt "a beautiful sunset over the mountains" \
--save-output
오프라인 MXFP8 양자화 (Offline MXFP8 Quantization (ModelSlim))
오프라인 양자화의 경우, msModelSlim으로 모델을 사전 양자화하고 결과 체크포인트를 로드하세요. 양자화 방식은 quant_model_description.json에서 자동 감지되므로 추가적인 --quantization 플래그가 필요 없어요.
1단계: msModelSlim으로 양자화
msmodelslim quant \
--model_path /path/to/wan2_2_float_weights \
--save_path /path/to/wan2_2_mxfp8_weights \
--device npu \
--model_type Wan2_2 \
--quant_type mxfp8 \
--trust_remote_code True
주의: SGLang은 양자화된 임베딩을 지원하지 않아요. msmodelslim을 사용할 때는 임베딩 양자화를 비활성화하세요.
2단계: Diffusers 형식으로 변환
msModelSlim은 양자화된 Wan2.2 가중치를 원래 Wan 형식으로 저장해요. 제공된 repack 스크립트를 사용해 Diffusers 형식으로 변환하세요:
python python/sglang/multimodal_gen/tools/wan_repack.py \
--input-path /path/to/wan2_2_mxfp8_weights \
--output-path /path/to/wan2_2_mxfp8_diffusers
그런 다음 원본 Diffusers 체크포인트의 모든 파일(transformer/transformer_2 폴더 제외)을 출력 디렉토리로 복사하세요.
3단계: 추론 실행
sglang generate \
--model-path /path/to/wan2_2_mxfp8_diffusers \
--prompt "a beautiful sunset over the mountains" \
--save-output
ModelScope에서 제공되는 사전 양자화 체크포인트는 modelscope/Eco-Tech를 참고하세요.