배포 및 성능 모드

배포 및 성능 모드 (Deployment and Performance Modes)

이 페이지는 SGLang Diffusion에서 --performance-mode, 컴포넌트 상주(residency), FSDP, CFG 병렬 처리, SP, TP를 선택하기 위한 실용적인 기본값을 제공해요. 목표(속도/메모리/다중 GPU)에 따라 가장 단순한 설정을 고르는 방법을 설명해요.

출처: 문서

본문

이 페이지는 --performance-mode, 컴포넌트 상주(residency), FSDP, CFG 병렬 처리, SP, TP를 선택하기 위한 실용적인 기본값을 제공해요.

빠른 규칙 (Quick Rule)

메모리 목표에 맞는 가장 단순한 설정을 사용해요:

Goal Recommended setting
모델이 맞을 때 가장 빠른 단일 GPU 실행 상주(resident) 컴포넌트를 사용하고 FSDP를 사용하지 않기.
더 낮은 단일 GPU 메모리 사용 컴포넌트 offload 사용, 완전한 컴포넌트가 편안하게 맞지 않을 때 레이어 단위 offload 사용.
더 빠른 다중 GPU Qwen/Wan CFG 생성 FSDP를 CFG 병렬 처리와 함께 사용하고 샤딩된 컴포넌트를 상주 유지.
시퀀스 길이 또는 비디오 형태 확장 모델이 시퀀스 병렬 처리를 활용할 때 SP/Ulysses/Ring 사용.
TP 호환성 또는 인코더 중심 경로 TP를 명시적으로 설정. TP를 기본 지연 시간 최적화로 취급하지 않기.

선택한 GPU의 사용 가능한 메모리를 기준으로 결정해요.

  • 다중 GPU 배포: 가장 적게 여유가 있는 선택 GPU가 병목이에요. 바쁜 80GiB GPU는 훨씬 더 작은 GPU처럼 동작할 수 있어요.
  • 단일 GPU 배포: FSDP는 가중치를 여러 GPU에 걸쳐 샤딩해요. 단일 GPU 배포를 한 GPU에 유지하는 데는 유용하지 않아요. 대신 컴포넌트 또는 레이어 단위 offload를 사용해요.

헬스 프로브 (Health Probes)

/liveness로 HTTP 프로세스가 살아 있는지, /health로 서버가 추론 준비가 되었는지 확인해요. 서버 기반 워밍업 중 /liveness200을, /health503을 반환해요. 모델 로딩과 컴파일을 위한 충분한 실패 예산으로 스타트업 프로브를 구성해요:

startupProbe:
  httpGet:
    path: /health
    port: 30010
  periodSeconds: 10
  failureThreshold: 180
readinessProbe:
  httpGet:
    path: /health
    port: 30010
livenessProbe:
  httpGet:
    path: /liveness
    port: 30010

상태 코드 계약과 워밍업 모드 동작은 Health endpoints를 참고해 주세요.

안정적인 모델 ID (Stable Model Identity)

복제본, 호스트 또는 체크포인트 마운트 경로를 가로질러 공개 모델 이름이 안정적으로 유지되어야 할 때 --served-model-name을 사용해요:

sglang serve \
  --model-path /mnt/checkpoints/Qwen-Image \
  --model-id Qwen-Image \
  --served-model-name image-production \
  --port 30010

해석된 공개 이름은 --served-model-name, 그다음 --model-id, 그다음 --model-path를 따르게 돼요. --model-id는 내부 모델 레지스트리 및 구성 해석 힌트로 남으며 배포 별칭의 대체가 아니에요. 해석된 이름은 /server_info/v1/models를 통해 노출되며, 요청이 자체 모델을 제공하지 않을 때 비디오 및 액션 응답에 사용돼요.

검색 및 검색 예시는 OpenAI API: Served model name을 참고해 주세요.

성능 모드 (Performance Modes)

--performance-mode는 명시적 offload, FSDP 또는 병렬 처리 플래그를 재정의하지 않고 안전한 프리셋을 적용해요. auto가 기본값이에요. 성능 관련 서버 인자를 명시적 사용자 제어 아래 두어야 할 때 manual을 사용해요. --mode는 짧은 별칭이에요.

Mode Meaning
manual 성능 관련 서버 인자를 명시적 사용자 제어 아래 유지.
auto 기본값. 레거시 안전 offload 기본값을 유지하고, FSDP가 DiT offload를 대체할 수 있는 검증된 다중 GPU 배포에서만 FSDP/CFG 사용.
speed 낮은 지연 시간과 높은 처리량을 위해 GPU 상주 실행을 선호. 미설정 시 CPU offload를 비활성화. torch.compile은 모델이 검증된 기본값을 가지거나 명시적으로 활성화되지 않으면 꺼짐. OOM 발생 가능.
memory 더 낮은 GPU 메모리를 선호. 컴포넌트 offload 또는 지원 시 Wan/MOVA 레이어 단위 DiT offload 사용.

auto는 FSDP를 적용하기 전에 선택된 GPU 메모리를 확인해요. 다중 GPU 실행에서는 선택된 GPU 중 가장 적게 사용 가능한 메모리를 사용하고, FSDP가 DiT offload를 대체할 수 있을 때만 자동으로 켜요. 선택된 GPU당 최소 45 GiB 사용 가능한 이미지 워크로드의 경우 반복 재사용되는 DiT를 상주 유지하고 큰 보조 인코더에는 레이어 단위 offload를 사용하며, 그 임계값 아래에서는 DiT를 offload된 상태로 유지해요. VAE 같은 모델별 컴포넌트는 구성된 메모리 임계값을 충족할 때만 상주하게 돼요. memory는 대신 VAE를 기본 레이어 단위 집합에 유지해 메모리 헤드룸을 최대화해요. 충분한 용량의 측정된 레시피에는 --component-residency vae=resident를 사용해요. 비디오 DiT 상주는 프레임 수와 해상도가 피크 메모리를 크게 바꾸므로 모델 및 워크로드별로 유지돼요. 모델 기본값이 CFG를 사용하고 사용자가 병렬 처리 정책을 설정하지 않았을 때 auto는 CFG 병렬 처리를 활성화할 수도 있어요. speed는 의도적으로 메모리를 확인하지 않아요. 지연 시간/처리량을 선호하고 OOM 위험을 수용하는 사용자를 위한 모드예요. torch.compile은 그 효과가 모델과 워크로드에 따라 다르므로 기본적으로 비활성화돼요. 모델별 배포 구성이 검증된 컴파일 경로를 활성화할 수 있으며 --enable-torch-compile true는 항상 명시적으로 옵트인해요.

이 모드들은 컴포넌트 상주 관리자에 선언된 네이티브 파이프라인 컴포넌트를 튜닝해요. DiT, 텍스트/이미지 인코더, VAE, vocoder, 어댑터, 업샘플러는 네이티브 모듈이 실행 가능한 레이어 구조를 선언할 때 레이어 단위 offload를 사용할 수 있어요. 지원되지 않는 컴포넌트를 명시적으로 선택하면 다른 상주 모드로 폴백하는 대신 시작 시 실패해요.

직접 제어하려면 --component-residency COMPONENT=MODEresident, component-offload, snapshot-offload 또는 layerwise-offload 중 하나를 할당해요:

sglang generate \
  --model-path Wan-AI/Wan2.2-T2V-A14B-Diffusers \
  --component-residency dit=layerwise-offload text_encoder=component-offload vae=resident

기존의 컴포넌트별 CPU-offload 및 레이어 단위 플래그는 계속 지원돼요. 정식 선택자(canonical selectors)는 일치하는 레거시 설정만 재정의하고, 일치하지 않는 레거시 설정과 자동 기본값은 유효하게 유지돼요. 완전한 우선순위 규칙은 Component Residency를 참고해 주세요.

torch.compile이 활성화되면 --offload-during-compile이 기본적으로 켜진 상태로 유지돼요. 컴파일 워밍업 중에는 max-autotune이 더 타이트한 메모리 GPU에 맞도록 DiT를 일시적으로 offload하고 상주 비-DiT 컴포넌트를 퇴출시킨 다음, 실제 트래픽 전에 구성된 서빙 상주를 복원해요.

Breakable CUDA graph는 지원되는 이미지 파이프라인을 위한 별도의 수동 옵트인이에요. --enable-breakable-cuda-graph를 활성화하면 워밍업이 일치하는 그래프 시그니처를 캡처하도록 모든 서빙 해상도를 --warmup-resolutions에 선언해요.

Note 프리셋은 의도적으로 거칠어요. 0.0에서 1.0 같은 미래의 연속 값이 속도-메모리 트레이드오프를 더 정밀하게 표현할 수 있지만, 모델별 메모리 모델과 더 명확한 사용자 기대가 필요해요. 그때까지는 프리셋과 오버라이드용 명시적 플래그를 함께 사용해요.

예시:

sglang generate \
  --model-path Qwen/Qwen-Image \
  --num-gpus 2 \
  --performance-mode auto
sglang generate \
  --model-path Wan-AI/Wan2.1-T2V-1.3B-Diffusers \
  --performance-mode memory

명시적 플래그는 모드보다 우선해요:

sglang generate \
  --model-path Qwen/Qwen-Image \
  --num-gpus 2 \
  --performance-mode auto \
  --use-fsdp-inference false

이 예시에서 auto는 FSDP를 다시 활성화하지 않아요. 병렬 처리에도 동일하게 적용되는데, 예를 들어 --enable-cfg-parallel false는 CFG 병렬 처리를 비활성화 상태로 유지해요.

레버 해석 (Interpreting The Levers)

Resident: 완전한 컴포넌트를 가속기 상에 유지해요. 메모리가 충분할 때 보통 가장 빠르다.

Component offload: 선언된 사용 사이에 완전한 컴포넌트를 CPU에 유지해요. 단순하고 견고하지만 각 사용이 전체 컴포넌트 전송을 지불해요.

Layerwise offload: 지원되는 모든 네이티브 가중치 컴포넌트의 선언된 레이어를 스트리밍해요. 피크 가속기 메모리를 더 낮추지만 지연 시간을 늘리고 처리량을 낮출 수 있어요.

어떤 컴포넌트를 스트리밍할까 (Which components to stream)

--layerwise-offload-components는 목록을 받으며, 더 많다고 더 좋은 것은 아니에요. 스트리밍은 컴포넌트가 실행될 때마다 그 가중치의 host-to-device 전송을 한 번 지불하며, 그 실행의 컴퓨트와 겹쳐요. 중요한 것은 크기가 아니라 요청당 얼마나 자주 실행되는지예요.

  • DiT는 디노이징 스텝당 한 번 실행돼요. 그 전송은 모든 스텝에 걸쳐 상각되고 어텐션 뒤에 숨겨지므로, 레이어 단위 offload가 대상으로 하는 컴포넌트예요.
  • 비디오 VAE는 한 번이 아니라 시간 청크당 한 번 실행돼요. H3의 디코더는 각 청크에 대해 전체를 다시 실행하므로 블록 스트리밍은 청크당 한 번 그 전송을 지불해요.
  • 텍스트 인코더는 한 번 실행돼요. 맞으면 상주 유지하고, 그렇지 않으면 블록을 상주시킨 채 스트리밍해요.

세 종류의 배치가 있고 두 종류가 아니에요. 컴포넌트는 목록에 있어도 여전히 블록을 보유할 수 있어요 — --layerwise-offload-components dit,text_encoder,vae--layerwise-resident-layers video_vae=36과 함께 쓰면 pass마다가 아니라 한 번 전송하고, 컴포넌트가 끝나면 VRAM을 다시 돌려주며 디노이즈 동안 보유하지 않아요. MiniMax-H3의 864x480 / 124 프레임에서 이는 150초 스트리밍 대비 13초의 디코드에 해당해요.

그 반환은 기본 수명인 forward이며, DiT의 상주 레이어와 VAE의 것이 하나의 예산을 공유하게 해줘요. 각 집합은 컴포넌트가 실행되는 동안만 GPU에 있어요. 두 집합이 동시에 맞으면, --layerwise-residency-lifetime video_vae=permanent(또는 DiT의 경우 --dit-layerwise-residency-lifetime permanent)는 대신 로드 시 배치해요 — 요청당 전송이 없고, 오지 않을 재로드를 위해 고정된 호스트 복사본도 없어요. 거래는 피크 메모리예요. permanent는 모든 컴포넌트의 상주 집합을 함께 더하고, forward는 가장 큰 것만 더해요. 합이 맞지 않는 카드에서 permanent는 천천히 실패하는 대신 시작 시 실패해요. 그곳에서는 forward를 유지하세요.

소비자 카드에서 거래는 보통 나쁘므로, 사용하기 전에 측정해요. 한 RTX 5090(1024px, 40스텝, 3개의 interleaved round, 요청 각 5개)의 Qwen-Image-2.1에서 텍스트 인코더의 상주 집합을 permanent로 만들기:

text_encoder resident p50 vs forward peak at load of a 31.4 GiB card
none (기본값) 13.53 s 25168 MiB 78%
0.3 permanent 13.45 s −0.6% 29570 MiB 92%
0.5 permanent 13.41 s −0.8% 31480 MiB 98%
0.8 permanent 13.37 s −1.2% 32092 MiB 100%

모든 round가 0.1%로 재현되고 순서가 일관되므로 이득은 실재하고 — 데스크톱도 돌리는 머신에서 카드의 남은 헤드룸 거의 전부를 0.6%~1.2%와 맞바꾼 것이에요. 카드가 빠를수록 저장된 전송이 차지하는 비중은 더 작아요. 같은 플래그는 기준선이 14.14초였던 더 느린 박스에서 −2.8%로 측정됐어요. 출력은 일반적인 부동소수점 재정렬 안에 있어요(0.5는 기본값과 비트 동일, 0.8은 하나의 LSB를 넘는 픽셀 없이 최대 1/255 편차).

permanent는 한 사용이 많은 pass를 만들고 합이 여전히 맞을 때 — 데이터센터 카드, 또는 그 집합이 예산에 비해 작은 컴포넌트 — 메모리를 벌어요.

그러므로 "목록에서 빼라"를 일회성 컴포넌트의 해결책으로 읽지 마세요. 그것은 프로세스 내내 상주하게 해요. 어느 쪽에도 상주 블록이 없으면 H3의 10.4GB 비디오 VAE를 목록에서 빼는 것이 한 RTX 4090에서 디코드를 39.9초에서 5.3초로 만들었어요 — 하지만 피크 5.8GB도 추가했으며, 이는 12GB 카드가 갖지 못한 예산이에요.

프리페치를 얼마나 깊게 (How deep to prefetch)

--dit-offload-prefetch-size는 단조적이지 않아요. 더 깊은 프리페치는 복사의 더 많은 부분을 숨기지만 그 스테이징 버퍼가 활성화를 몰아내므로 지연 시간이 다시 올라가고 피크 메모리가 계속 상승해요. 위 H3 구성에서 1/2/3/4 레이어가 17.3 / 15.3 / 15.8 / 16.7초의 디노이즈로 측정됐고, 가장 깊은 설정은 24GB 카드의 96%에 도달했어요. 기본값을 신뢰하지 말고 두세 값을 스윕해요.

신경 쓰지 않아도 될 때 (When not to bother)

상주 또는 프리페치를 튜닝하기 전에 전송이 노출되는지 측정하고, 체크포인트 크기에서 추론하지 말고 측정해요. 대역폭을 초과하는 바이트는 노출될 수 있는 것의 상한을 정하지, 실제가 아니에요. 프리페치는 정확히 그것을 숨기기 위해 존재하니까요.

1.3B 비디오 DiT는 스텝당 약 2.6GB를 옮기며, 전혀 겹치지 않으면 1초 스텝의 대략 1/10이고, 상주 설정은 평평하게 측정돼요. 겹치므로 회복할 것이 없어요. 레이어당 1.4GB의 50-레이어 모델은 스텝당 66GB를 옮기며, 거기서 같은 플래그가 모델이 전혀 실행될지 결정해요. 대상 구성에서 두세 값을 스윕하고 측정된 승자를 유지해요.

FSDP는 DiT 가중치를 여러 GPU에 걸쳐 샤딩하고 forward 중에 가중치를 all-gather해요. 다중 GPU 배포, 특히 검증된 Wan I2V 워크로드에서 DiT CPU offload 비용을 줄일 수 있어요.

FSDP 샤딩 입도가 중요해요. SGLang Diffusion은 transformer_blocks.0 또는 blocks.0 같은 반복 transformer 블록 항목을 직접 샤딩하는 것을 선호해요. 더 거친 샤딩은 래퍼 수를 낮추지만 all-gather 피크 메모리를 늘릴 수 있고, 더 미세한 샤딩은 일시 메모리를 줄일 수 있지만 통신과 스케줄링 오버헤드를 추가해요. 모델이 명시적 샤딩 규칙을 정의하지 않으면 로더는 반복 블록 클래스 이름과 일반적인 직접 번호 블록 경로로 폴백해요.

CFG 병렬 처리는 긍정/부정 CFG 브랜치를 GPU에 걸쳐 분할해요. 정상 단계 수의 Qwen/Wan 워크로드에서 이것이 지금까지 관측된 가장 신뢰할 수 있는 다중 GPU 속도 향상이에요.

SP/Ulysses/Ring은 시퀀스 작업을 분할해요. 비디오 워크로드에 도움이 될 수 있지만 검증된 Qwen/Wan 실행은 지연 시간에서 CFG 병렬 처리가 SP를 능가하는 것을 보여줬어요.

TP는 호환성과 일부 모델 구조를 위해 지원되지만, 현재 측정은 Qwen/Wan의 기본 지연 시간 경로로 만들지 않아요.

현재 벤치마크 시사점 (Current Benchmark Takeaways)

관측된 정규 규모 추세:

  • Z-Image: 테스트된 설정에서 단일 GPU no-offload가 FSDP/SP보다 빨랐어요. 메모리나 병렬 처리가 요구하지 않으면 FSDP를 꺼 두어요.
  • Qwen-Image: 대상 하드웨어에서 특정 FSDP/SP/Ring 설정을 벤치마크하지 않았으면 기본 비-FSDP 경로를 유지해요.
  • Wan: FSDP는 검증된 다중 GPU 워크로드에서 DiT offload를 대체할 수 있지만, 텍스트/이미지 인코더는 여전히 컴포넌트 offload가 필요할 수 있어요. 경로에 대해 FSDP를 자동화하기 전에 모델별 정밀도 검사를 유지해요.
  • 컴포넌트 offload는 주로 메모리를 줄였고, 테스트된 no-offload-vs-offload 실행에서 지연 시간은 개선하지 않았어요.

프로덕션 기본값을 고정하기 전에 항상 실제 해상도, 프레임 수, 스텝 수, GPU 유형으로 벤치마크해요.

더 알아보기