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) 레이어에 대한 독립적인 양자화 결정을 추가할 예정이에요.

Ascend에서의 ModelSlim 지원

양자화 방식 레이어 유형 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

Ascend에서의 AWQ 지원:

양자화 방식 레이어 유형 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

Ascend에서의 Auto-round 지원

양자화 방식 레이어 유형 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

Ascend에서의 GGUF 지원

양자화 유형 레이어 유형 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_matmulnpu_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와 일치) 전치돼요.
  • 순방향: AscendTPDispatchernpu_moe_init_routing_v2(quant_mode=3)을 실행하며, 이는 토큰별 MX 활성화 양자화를 라우팅에 통합해요(e4m3 페이로드 + e8m0 블록 스케일, 페어 분할 레이아웃으로 reshape). AscendRunnerCore는 gmm1 npu_grouped_matmul_swiglu_quant_v2(누적 group_list; gate/up + swiglu + requant를 통합해 별도의 활성화 단계가 없어요) → gmm2 npu_grouped_matmul(count group_list)을 실행해요. UE8M0(float8_e8m0fnu) 스케일 dtype은 명시적으로 전달되고 e4m3 x/weight dtype은 암시적으로 남겨져요.
  • 라우터 게이트: 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_x2 dtype 객체를 거부해요.
  • 온라인과 오프라인은 같은 커널 경로와 레이아웃을 공유해요. 가중치 소스(로드 시 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 w13w2 전문가 가중치를 제공해요.
  • 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를 내보내지 못하고 루프에 빠질 수 있었어요).
  • 오프라인 (ModelSlimMXFP4SchemeNPUSingleLevelMXFP4OfflineLinearMethod)은 단일 레벨이에요: 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_x2 dtype 객체를 거부해요.
  • 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 w13w2 전문가 가중치를 제공해요.
  • 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를 참고하세요.

더 알아보기 (Learn more)