FP8 ViT 인코더 어텐션

FP8 ViT 인코더 어텐션 (FP8 ViT Encoder Attention)

큰 이미지(예: QHD, 4K)와 상대적으로 짧은 텍스트 프롬프트/생성을 다루는 시각 이해 워크로드에서는, 텍스트 모델이 양자화되어 있을 때(예: NVFP4) ViT 인코더 어텐션이 상당한 병목이 될 수 있어요. vLLM은 NVIDIA GPU의 FlashInfer cuDNN과 AMD GPU의 AITER를 통해 ViT 인코더 어텐션에 선택적 FP8 양자화를 지원합니다. Q/K/V는 어텐션 호출 직전에 즉시 FP8로 양자화됩니다.

참고:

  • 현재 Qwen3-VL 계열 모델(qwen3_vl, qwen3_vl_moe, qwen3_5, qwen3_5_moe, 그리고 Qwen3 ViT를 사용하는 다른 모델)만 지원합니다.
  • 동적 스케일링은 ViT 전체 CUDA 그래프와 호환되지 않습니다.
  • 성능 이점은 대부분 QHD/4K 해상도나 멀티이미지 요청에서 드러납니다. 작은 이미지는 양자화 오버헤드(양자화 커널 3회 실행 + 언패딩) 때문에 속도 향상이 없을 수 있습니다.
  • FP8 텐서코어 속도 향상은 GB200보다 GB300에서 더 두드러집니다.
  • ROCm에서는 packed 가변 길이 이미지 및 비디오 배치가 AITER의 네이티브 varlen FP8 어텐션으로 지원됩니다.

출처: 문서

본문

요구 사항 (Requirements)

  • NVIDIA: cuDNN >= 9.17.1인 FlashInfer cuDNN 백엔드.
  • AMD: gfx942(MI300 시리즈) 또는 gfx950(MI350 시리즈)에서 flash_attn_varlen_fp8_pertensor_func 지원이 있는 AITER.

사용법 (Usage)

--mm-encoder-attn-dtype fp8 를 전달하고 현재 플랫폼의 백엔드를 선택해 FP8 ViT 어텐션을 활성화합니다.

vllm serve $MODEL \
    --mm-encoder-attn-backend FLASHINFER \
    --mm-encoder-attn-dtype fp8

# AMD ROCm
vllm serve $MODEL \
    --mm-encoder-attn-backend ROCM_AITER_FA \
    --mm-encoder-attn-dtype fp8

기본적으로(스케일 파일 없음) 동적 스케일링 이 사용됩니다. 관찰된 Q/K/V amax 값의 16-항목 순환 버퍼가 per-forward 스케일 업데이트를 주도합니다. 이는 보정 없이 BF16 정확도를 맞추지만 약간의 per-forward 오버헤드를 추가합니다.

캘리브레이션-원회, 재사용 워크플로우 (권장, Calibrate-Once, Reuse Workflow)

프로덕션에서는 대표 데이터셋에서 정적 스케일을 한 번 캘리브레이션하고 재사용해 동적 오버헤드를 피하세요.

# Step 1: calibrate and save scales (runs dynamic scaling for 16 passes,
# then dumps the learned scales to JSON).
vllm bench mm-processor \
    --model $MODEL --mm-encoder-attn-backend $MM_ATTN_BACKEND \
    --mm-encoder-attn-dtype fp8 \
    --mm-encoder-fp8-scale-save-path /path/to/scales.json \
    --dataset-name hf --dataset-path lmarena-ai/VisionArena-Chat \
    --num-prompts 100

# Step 2: serve with static scales (no dynamic overhead).
vllm serve $MODEL \
    --mm-encoder-attn-backend $MM_ATTN_BACKEND \
    --mm-encoder-attn-dtype fp8 \
    --mm-encoder-fp8-scale-path /path/to/scales.json

저장된 스케일은 --mm-encoder-fp8-scale-save-margin(기본 1.5)만큼 곱해져 보정 세트에 없는 활성화 이상치에 대한 여유를 남깁니다. 이 기본값은 데이터셋 전반에 일반화되는 것으로 검증되었습니다(예: VisionArena-Chat 캘리브레이션이 ChartQA에서 BF16 정확도를 유지).

스케일 파일 형식 (Scale File Format)

{
    "visual.blocks.0.attn.attn": {"q": 224.0, "k": 198.0, "v": 210.0},
    "visual.blocks.1.attn.attn": {"q": 218.0, "k": 195.0, "v": 207.0}
}

q_scale / k_scale / v_scale 키도 별칭으로 허용됩니다.

성능 (Performance)

코어 cuDNN 어텐션 커널(PyTorch profiler, cudnn_generated_fort_native_sdpa_sm100_flash_fprop, head_dim=128, seq_len=8192):

하드웨어 BF16 FP8 Speedup
GB200 350 us 312 us 1.12x
GB300 300 us 211 us 1.42x

종단 간 인코더 순방향 시간(GB200의 Qwen3-VL-30B-A3B-Instruct, 요청당 3개 이미지):

해상도 BF16 중앙값 FP8 중앙값 Speedup
HD (720x1280) 31.77 ms 36.39 ms 0.87x
FullHD (1080x1920) 57.99 ms 58.73 ms ~same
QHD (1440x2560) 131.83 ms 122.30 ms 1.08x
4K (2160x3840) 543.44 ms 460.31 ms 1.18x

크로스오버는 요청당 3개 이미지의 FullHD 부근입니다. QHD 이상에서는 FP8이 이깁니다.

MI300X의 완전한 AITER 어텐션 호출(BF16 입력, 16 헤드, head_dim=72; FP8은 Q/K/V 양자화 포함):

시퀀스 길이 AITER BF16 AITER FP8 Speedup
2304 0.467 ms 0.337 ms 1.38x
4096 0.812 ms 0.764 ms 1.06x
8192 2.555 ms 2.364 ms 1.08x
16384 9.769 ms 8.655 ms 1.13x

정확도 (Accuracy)

ChartQA, Qwen3-VL-8B-Instruct, 500 샘플. FP8 static은 VisionArena-Chat에서 캘리브레이션된 스케일(기본 1.5x 마진)을 사용합니다.

메트릭 BF16 FP8 dynamic FP8 static
relaxed_accuracy 0.780 0.776 0.780
anywhere_accuracy 0.806 0.816 0.814
exact_match 0.584 0.582 0.578

세 구성 모두 통계적 노이즈 범위 내에서 일치하며, 한 데이터셋에서 캘리브레이션한 정적 스케일이 다른 데이터셋에도 일반화된다는 것을 확인해 줍니다.

더 알아보기 (Learn more)