PD 분리

PD 분리 (PD Disaggregation)

SGLang에는 추론 성능을 끌어올리는 데 가장 큰 임팩트를 주는 기능 중 하나로 Prefill–Decode(PD) 분리가 있어요. 이름 그대로 프리필과 디코드를 분리하는 건데, 왜 필요한지부터 살펴볼게요.

PD 분리가 뭐고 왜 필요한가?

LLM 추론은 프리필(Prefill)디코드(Decode) 라는 서로 다른 두 단계로 나뉘어요. 프리필은 입력 시퀀스 전체를 처리하는 계산 집약적(compute-intensive) 단계고, 디코드는 토큰 생성 중 Key-Value(KV) 캐시를 관리하는 메모리 집약적(memory-intensive) 단계예요. 전통적으로 이 두 단계를 하나의 통합 엔진에서 처리했는데, 프리필 배치와 디코드 배치를 함께 스케줄링하다 보니 비효율이 생겼어요. SGLang은 이 문제를 해결하려고 PD 분리를 도입했어요.

통합 스케줄링의 문제

프리필 배치와 디코드 배치를 함께 처리하는 기존의 통합 엔진은 두 가지 큰 문제를 일으켜요:

  1. 프리필 인터럽션: 들어오는 프리필 배치가 실행 중인 디코드 배치를 자주 끊어서, 토큰 생성에 상당한 지연이 생겨요.
  2. DP Attention 불균형: 데이터 병렬(DP) attention에서 한 DP 워커는 프리필 배치를, 다른 워커는 디코드 배치를 동시에 처리할 수 있어서 디코드 지연이 늘어나요.

PD 분리는 두 단계를 분리해 이 문제들을 해결하고, 각 단계에 맞춘 최적화를 가능하게 해요.

설계 세부사항은 이 문서를 참고하세요.

현재 전송 엔진으로는 MooncakeNIXL을 지원해요.

PD 분리 모드에서 프로파일링

PD 분리 모드에서 프리필·디코드 워커를 프로파일해야 한다면, 벤치마크와 프로파일링 가이드의 PD 분리 모드 프로파일 섹션을 참고하세요. torch 프로파일러의 제약 때문에 프리필·디코드 워커는 전용 커맨드라인 옵션으로 따로 프로파일해야 해요.

라우터 통합

PD 분리를 대규모로 배포하면서 로드 밸런싱과 장애 허용(fault tolerance)까지 챙기고 싶다면, SGLang이 제공하는 라우터를 쓰면 돼요. 라우터는 다양한 라우팅 정책으로 요청을 프리필·디코드 인스턴스에 분산할 수 있어요. PD 분리 라우팅 설정(설정 옵션과 배포 패턴 포함)에 대한 자세한 내용은 SGLang Model Gateway(전 라우터)을 참고하세요.

Mooncake

요구사항

uv pip install mooncake-transfer-engine

IB 장치 설정

Mooncake 백엔드를 쓸 때 --disaggregation-ib-device는 다음 형식을 지원해요:

  1. 모든 GPU 공유 장치 목록: mlx5_0 또는 mlx5_0,mlx5_1
  2. GPU별 JSON 매핑: {"0": "mlx5_0,mlx5_1", "1": "mlx5_2,mlx5_3"}
  3. 같은 GPU별 매핑을 담은 JSON 파일 경로

각 JSON 값은 공유 설정과 같은 콤마로 구분된 장치 목록 형식을 사용해요.

사용법

Llama 단일 노드

python -m sglang.launch_server \
  --model-path meta-llama/Llama-3.1-8B-Instruct \
  --disaggregation-mode prefill \
  --port 30000 \
  --disaggregation-ib-device mlx5_roce0
python -m sglang.launch_server \
  --model-path meta-llama/Llama-3.1-8B-Instruct \
  --disaggregation-mode decode \
  --port 30001 \
  --base-gpu-id 1 \
  --disaggregation-ib-device mlx5_roce0
python -m sglang_router.launch_router --pd-disaggregation --prefill http://127.0.0.1:30000 --decode http://127.0.0.1:30001 --host 0.0.0.0 --port 8000

DeepSeek 멀티 노드

# prefill 0
python -m sglang.launch_server \
  --model-path deepseek-ai/DeepSeek-V3-0324 \
  --disaggregation-ib-device ${device_name} \
  --disaggregation-mode prefill \
  --host ${local_ip} \
  --port 30000 \
  --trust-remote-code \
  --dist-init-addr ${prefill_master_ip}:5000 \
  --nnodes 2 \
  --node-rank 0 \
  --tp-size 16 \
  --dp-size 8 \
  --enable-dp-attention \
  --moe-a2a-backend deepep \
  --mem-fraction-static 0.8
# prefill 1
python -m sglang.launch_server \
  --model-path deepseek-ai/DeepSeek-V3-0324 \
  --disaggregation-ib-device ${device_name} \
  --disaggregation-mode prefill \
  --host ${local_ip} \
  --port 30000 \
  --trust-remote-code \
  --dist-init-addr ${prefill_master_ip}:5000 \
  --nnodes 2 \
  --node-rank 1 \
  --tp-size 16 \
  --dp-size 8 \
  --enable-dp-attention \
  --moe-a2a-backend deepep \
  --mem-fraction-static 0.8
# decode 0
python -m sglang.launch_server \
  --model-path deepseek-ai/DeepSeek-V3-0324 \
  --disaggregation-ib-device ${device_name} \
  --disaggregation-mode decode \
  --host ${local_ip} \
  --port 30001 \
  --trust-remote-code \
  --dist-init-addr ${decode_master_ip}:5000 \
  --nnodes 2 \
  --node-rank 0 \
  --tp-size 16 \
  --dp-size 8 \
  --enable-dp-attention \
  --moe-a2a-backend deepep \
  --mem-fraction-static 0.8 \
  --max-running-requests 128
# decode 1
python -m sglang.launch_server \
  --model-path deepseek-ai/DeepSeek-V3-0324 \
  --disaggregation-ib-device ${device_name} \
  --disaggregation-mode decode \
  --host ${local_ip} \
  --port 30001 \
  --trust-remote-code \
  --dist-init-addr ${decode_master_ip}:5000 \
  --nnodes 2 \
  --node-rank 1 \
  --tp-size 16 \
  --dp-size 8 \
  --enable-dp-attention \
  --moe-a2a-backend deepep \
  --mem-fraction-static 0.8 \
  --max-running-requests 128

고급 설정

Mooncake와 함께 쓰는 PD 분리는 시스템 동작을 세밀하게 제어하는 다음 환경변수를 지원해요.

NVLink 전송 설정

mooncake 백엔드에서 KV 캐시 전송에 NVLink 전송을 쓰려면(NVL72 배포에 권장) 다음 환경변수를 설정해요. 보조 데이터 전송은 임시 해결책으로 여전히 TCP를 사용한다는 점을 기억하세요.

export SGLANG_MOONCAKE_CUSTOM_MEM_POOL=NVLINK
export MC_FORCE_MNNVL=True

mooncake 백엔드에서 KV 캐시 전송에 인트라-노드 NVLink를 이용하려면(A100, H20, H100 등에 권장) 다음 환경변수를 설정해요. 보조 데이터는 여전히 TCP로 전송해야 해요.

export SGLANG_MOONCAKE_CUSTOM_MEM_POOL=INTRA_NODE_NVLINK
export MC_INTRANODE_NVLINK=true

SGLANG_MOONCAKE_CUSTOM_MEM_POOL 환경변수는 커스텀 메모리 풀을 활성화해요. 지원 값은 NVLINK(또는 True), BAREX, INTRA_NODE_NVLINK예요.

프리필 서버 설정

변수 설명 기본값
SGLANG_DISAGGREGATION_THREAD_POOL_SIZE TP 랭크당 KVCache 전송 작업용 워커 스레드 총 수 제어 int(0.75 * os.cpu_count()) // 8로 계산된 동적 값. 효율성을 보장하고 스레드 경쟁 상태를 막기 위해 4보다 크고 12보다 작게 제한
SGLANG_DISAGGREGATION_QUEUE_SIZE 병렬 전송 큐 수 설정. 여러 디코드 인스턴스의 KVCache 전송 요청이 이 큐들에 샤딩되어 스레드와 전송 대역폭을 동시에 공유. 1로 설정하면 fcfs 전략으로 요청을 하나씩 전송 4
SGLANG_MOONCAKE_MAX_TRANSFER_BATCH_INDICES 하나의 동기식 전체 레이어 Mooncake 전송 배치로 표현되는 KV 캐시 인덱스 수의 opt-in 제한. 양수로 설정하면 연속 주소 범위가 형성되기 전에 더 큰 인덱스 배열을 순서 있는 하위 배치로 분할. 커스텀 메모리 풀 레이어별 경로는 변하지 않음 0 (비활성)
SGLANG_DISAGGREGATION_BOOTSTRAP_TIMEOUT 요청 초기화 중 목적지 KV 인덱스 수신 타임아웃(초) 300
SGLANG_DISAGGREGATION_BOOTSTRAP_ENTRY_CLEANUP_INTERVAL 부트스트랩 항목 정리 간격(초) 120

평균 TTFT가 더 커도 괜찮다면 export SGLANG_DISAGGREGATION_BOOTSTRAP_TIMEOUT=600 (10분)으로 타임아웃 조건을 완화할 수 있어요. 단, 이 설정은 실행 중인 디코드 노드가 연결을 끊을 때 프리필 인스턴스가 해당 메모리 리소스를 정리하는 데 더 오래 걸리게 해요.

디코드 서버 설정

변수 설명 기본값
SGLANG_DISAGGREGATION_HEARTBEAT_INTERVAL 프리필 부트스트랩 서버로의 헬스체크 간격(초) 5.0
SGLANG_DISAGGREGATION_HEARTBEAT_MAX_FAILURE 프리필 서버를 오프라인으로 표시하기 전 허용되는 연속 하트비트 실패 횟수 2
SGLANG_DISAGGREGATION_WAITING_TIMEOUT 요청 초기화 후 KV 캐시 수신 타임아웃(초) 300

평균 TTFT가 더 커도 괜찮다면 export SGLANG_DISAGGREGATION_WAITING_TIMEOUT=600 (10분)으로 타임아웃 조건을 완화할 수 있어요.

Heterogeneous TP와 GPU 스테이징 버퍼

프리필과 디코드가 서로 다른 텐서 병렬(TP) 크기를 쓸 때(예: 프리필 TP=4, 디코드 DP attention TP=1), 두 쪽의 KV 캐시 메모리 레이아웃이 달라져요. GPU 스테이징 버퍼는 프리필 쪽에서 KV 헤드 슬라이스를 연속 버퍼로 모아(gather) 대량 RDMA 전송을 수행한 뒤, 디코드 쪽의 올바른 KV 캐시 페이지로 분산(scatter)해 이 문제를 해결해요. 높은 동시성에서 기본 per-token 슬라이스 방식보다 2–5배 throughput 향상을 제공하고, 동종 TP 기준선과는 ~5% 이내로 일치해요.

프리필과 디코드가 다른 TP 크기를 쓸 때 Mooncake 전송 백엔드에서 스테이징 버퍼를 활성화해요. 양쪽이 같은 TP 크기를 쓰면 활성화해도 스테이징은 자동으로 우회돼요.

참고: 스테이징 버퍼는 비-MLA 모델(예: GQA, MHA)용으로 설계됐어요. MLA 모델(예: DeepSeek-V2/V3)은 이 플래그를 활성화하면 안 돼요.

환경변수

변수 설명 기본값
SGLANG_DISAGG_STAGING_BUFFER 이기종 TP KV 전송용 GPU 스테이징 버퍼 활성화 False
SGLANG_DISAGG_STAGING_POOL_SIZE_MB 디코드 쪽 링 버퍼 풀 총 크기(MB) 4096

사용 예시

# 프리필과 디코드 양쪽에서 스테이징 버퍼 환경변수 설정
export SGLANG_DISAGG_STAGING_BUFFER=1
export SGLANG_DISAGG_STAGING_POOL_SIZE_MB=4096

# TP=4 프리필
python -m sglang.launch_server \
  --model-path $MODEL_PATH \
  --disaggregation-mode prefill \
  --port 30000 \
  --tp 4 \
  --trust-remote-code \
  --disaggregation-ib-device mlx5_1,mlx5_2

# TP=1 디코드 (또는 유효 attention TP=1인 DP attention)
python -m sglang.launch_server \
  --model-path $MODEL_PATH \
  --disaggregation-mode decode \
  --port 30001 \
  --tp 4 \
  --dp 4 \
  --enable-dp-attention \
  --trust-remote-code \
  --disaggregation-ib-device mlx5_3,mlx5_4

# 라우터
python -m sglang_router.launch_router \
  --pd-disaggregation \
  --prefill http://127.0.0.1:30000 \
  --decode http://127.0.0.1:30001 \
  --host 0.0.0.0 --port 8000

NIXL

요구사항

pip로 설치해요.

pip install nixl

또는 소스에서 빌드 — UCX가 이미 설치돼 있다면 이 방식이 필요할 수 있어요.

git clone https://github.com/ai-dynamo/nixl.git
cd nixl
pip install . --config-settings=setup-args="-Ducx_path=/path/to/ucx"

사용법

Llama 단일 노드

python -m sglang.launch_server \
  --model-path meta-llama/Llama-3.1-8B-Instruct \
  --disaggregation-mode prefill \
  --port 30000 \
  --disaggregation-transfer-backend nixl
python -m sglang.launch_server \
  --model-path meta-llama/Llama-3.1-8B-Instruct \
  --disaggregation-mode decode \
  --port 30001 \
  --base-gpu-id 1 \
  --disaggregation-transfer-backend nixl
python -m sglang_router.launch_router --pd-disaggregation --prefill http://127.0.0.1:30000 --decode http://127.0.0.1:30001 --host 0.0.0.0 --port 8000

DeepSeek 멀티 노드

# prefill 0
python -m sglang.launch_server \
  --model-path deepseek-ai/DeepSeek-V3-0324 \
  --disaggregation-transfer-backend nixl \
  --disaggregation-mode prefill \
  --host ${local_ip} \
  --port 30000 \
  --trust-remote-code \
  --dist-init-addr ${prefill_master_ip}:5000 \
  --nnodes 2 \
  --node-rank 0 \
  --tp-size 16 \
  --dp-size 8 \
  --enable-dp-attention \
  --moe-a2a-backend deepep \
  --mem-fraction-static 0.8
# prefill 1
python -m sglang.launch_server \
  --model-path deepseek-ai/DeepSeek-V3-0324 \
  --disaggregation-transfer-backend nixl \
  --disaggregation-mode prefill \
  --host ${local_ip} \
  --port 30000 \
  --trust-remote-code \
  --dist-init-addr ${prefill_master_ip}:5000 \
  --nnodes 2 \
  --node-rank 1 \
  --tp-size 16 \
  --dp-size 8 \
  --enable-dp-attention \
  --moe-a2a-backend deepep \
  --mem-fraction-static 0.8
# decode 0
python -m sglang.launch_server \
  --model-path deepseek-ai/DeepSeek-V3-0324 \
  --disaggregation-transfer-backend nixl \
  --disaggregation-mode decode \
  --host ${local_ip} \
  --port 30001 \
  --trust-remote-code \
  --dist-init-addr ${decode_master_ip}:5000 \
  --nnodes 2 \
  --node-rank 0 \
  --tp-size 16 \
  --dp-size 8 \
  --enable-dp-attention \
  --moe-a2a-backend deepep \
  --mem-fraction-static 0.8 \
  --max-running-requests 128
# decode 1
python -m sglang.launch_server \
  --model-path deepseek-ai/DeepSeek-V3-0324 \
  --disaggregation-transfer-backend nixl \
  --disaggregation-mode decode \
  --host ${local_ip} \
  --port 30001 \
  --trust-remote-code \
  --dist-init-addr ${decode_master_ip}:5000 \
  --nnodes 2 \
  --node-rank 1 \
  --tp-size 16 \
  --dp-size 8 \
  --enable-dp-attention \
  --moe-a2a-backend deepep \
  --mem-fraction-static 0.8 \
  --max-running-requests 128

고급 설정

NIXL 백엔드 선택

기본적으로 NIXL은 KV 캐시 전송에 UCX 백엔드를 사용해요. 인프라에 맞게 SGLANG_DISSAGGREGATION_NIXL_BACKEND 환경변수로 다른 NIXL 플러그인 백엔드를 선택할 수 있어요.

예시: export SGLANG_DISAGGREGATION_NIXL_BACKEND=LIBFABRIC

가용 백엔드: UCX(기본), LIBFABRIC, 또는 설치된 모든 NIXL 플러그인.

사용 예시:

export SGLANG_DISAGGREGATION_NIXL_BACKEND=LIBFABRIC
python -m sglang.launch_server \
  --model-path meta-llama/Llama-3.1-8B-Instruct \
  --disaggregation-mode prefill \
  --disaggregation-transfer-backend nixl \
  --port 30000

ASCEND

사용법

memfabric_hybrid와 ASCEND_MF_STORE_URL 설정과 함께 ascend 백엔드를 사용해요.

pip install memfabric-hybrid==1.0.0
export ASCEND_MF_STORE_URL="tcp://xxx.xx.xxx.xxx:xxxx"

mooncake 백엔드를 사용해요. 자세한 내용은 mooncake 섹션에서 찾을 수 있어요.

export ENABLE_ASCEND_TRANSFER_WITH_MOONCAKE=true

ASCEND_NPU_PHY_ID를 컨테이너 환경에 설정해야 해요.

export ASCEND_NPU_PHY_ID=xxx

MIMO 단일 노드

prefill

# 고성능 cpu
echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
sysctl -w vm.swappiness=0
sysctl -w kernel.numa_balancing=0
sysctl -w kernel.sched_migration_cost_ns=50000
# cpu 바인딩
export SGLANG_SET_CPU_AFFINITY=1

unset https_proxy
unset http_proxy
unset HTTPS_PROXY
unset HTTP_PROXY
unset ASCEND_LAUNCH_BLOCKING
# cann
source /usr/local/Ascend/ascend-toolkit/set_env.sh
source /usr/local/Ascend/nnal/atb/set_env.sh

export STREAMS_PER_DEVICE=32
export SGLANG_DEEPEP_NUM_MAX_DISPATCH_TOKENS_PER_RANK=32
export HCCL_BUFFSIZE=1600
export HCCL_OP_EXPANSION_MODE=AIV
export HCCL_SOCKET_IFNAME=lo
export GLOO_SOCKET_IFNAME=lo
export SGLANG_NPU_PROFILING=0
export SGLANG_NPU_PROFILING_STAGE="prefill"
export DEEPEP_NORMAL_LONG_SEQ_ROUND=32
export DEEPEP_NORMAL_LONG_SEQ_PER_ROUND_TOKENS=3584
export ASCEND_MF_STORE_URL="tcp://127.0.0.1:24669"
export SGLANG_DISAGGREGATION_BOOTSTRAP_TIMEOUT=3600
export SGLANG_DISAGGREGATION_WAITING_TIMEOUT=3600
export SGLANG_ENABLE_OVERLAP_PLAN_STREAM=0
export DEEP_NORMAL_MODE_USE_INT8_QUANT=1
export SGLANG_DEEPEP_BF16_DISPATCH=0
export ASCEND_USE_FIA=1

python3 -m sglang.launch_server \
        --model-path /path/to/MiMo-V2-Flash-w8a8-all-0512 \
        --attention-backend ascend \
        --device npu \
        --tp-size 8 --nnodes 1 --node-rank 0 \
        --chunked-prefill-size -1 \
        --trust-remote-code --port 10000 \
        --host 127.0.0.1 --max-running-requests 16 \
        --mem-fraction-static 0.8 \
        --disaggregation-mode prefill --disaggregation-transfer-backend ascend \
        --disaggregation-bootstrap-port 8996 \
        --base-gpu-id 0 \
        --disable-radix-cache \
        --disable-cuda-graph \
        --moe-a2a-backend deepep --deepep-mode normal \
        # 2>&1 | tee $SGLANG_LOG_PATH

decode

# 고성능 cpu
echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
sysctl -w vm.swappiness=0
sysctl -w kernel.numa_balancing=0
sysctl -w kernel.sched_migration_cost_ns=50000
# cpu 바인딩
export SGLANG_SET_CPU_AFFINITY=1

unset https_proxy
unset http_proxy
unset HTTPS_PROXY
unset HTTP_PROXY
unset ASCEND_LAUNCH_BLOCKING
# export ASCEND_LAUNCH_BLOCKING=1

# cann
source /usr/local/Ascend/ascend-toolkit/set_env.sh
source /usr/local/Ascend/nnal/atb/set_env.sh

export STREAMS_PER_DEVICE=32
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
export SGLANG_DEEPEP_NUM_MAX_DISPATCH_TOKENS_PER_RANK=256
export HCCL_BUFFSIZE=1600
export HCCL_OP_EXPANSION_MODE=AIV
export HCCL_SOCKET_IFNAME=lo
export GLOO_SOCKET_IFNAME=lo
export SGLANG_NPU_PROFILING=0
export SGLANG_NPU_PROFILING_STAGE="prefill"
export DEEPEP_NORMAL_LONG_SEQ_ROUND=32
export DEEPEP_NORMAL_LONG_SEQ_PER_ROUND_TOKENS=3584
export ASCEND_MF_STORE_URL="tcp://127.0.0.1:24669"
export SGLANG_DISAGGREGATION_BOOTSTRAP_TIMEOUT=3600
export SGLANG_DISAGGREGATION_WAITING_TIMEOUT=3600
export SGLANG_ENABLE_OVERLAP_PLAN_STREAM=0
export DEEP_NORMAL_MODE_USE_INT8_QUANT=1
export SGLANG_DEEPEP_BF16_DISPATCH=0
export ASCEND_USE_FIA=1

python3 -m sglang.launch_server \
        --model-path  /path/to/MiMo-V2-Flash-w8a8-all-0512 \
        --attention-backend ascend \
        --device npu \
        --tp-size 8 --nnodes 1 --node-rank 0 \
        --trust-remote-code --port 10001 \
        --host 127.0.0.1 --max-running-requests 16 \
        --mem-fraction-static 0.8 \
        --disaggregation-mode decode --disaggregation-transfer-backend ascend \
        --disaggregation-bootstrap-port 8996 \
        --base-gpu-id 8 \
        --disable-radix-cache \
        --cuda-graph-bs-decode 1 2 4 8 10 12 14 16 \
        --speculative-draft-model-quantization unquant \
        --speculative-algorithm EAGLE --speculative-num-steps 3 --speculative-eagle-topk 1 --speculative-num-draft-tokens 4 \
        --enable-multi-layer-eagle \
        --moe-a2a-backend deepep --deepep-mode low_latency \
        # 2>&1 | tee $SGLANG_LOG_PATH

router

python -m sglang_router.launch_router \
    --pd-disaggregation \
    --prefill http://127.0.0.1:10000 \
    --decode  http://127.0.0.1:10001 \
    --host 127.0.0.1 \
    --port 9903 \
    --health-check-interval-secs 3600 \
    --mini-lb \

DeepSeek 멀티 노드

환경

echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
sysctl -w vm.swappiness=0
sysctl -w kernel.numa_balancing=0
sysctl -w kernel.sched_migration_cost_ns=50000

export SGLANG_SET_CPU_AFFINITY=1

unset https_proxy
unset http_proxy
unset HTTPS_PROXY
unset HTTP_PROXY
unset ASCEND_LAUNCH_BLOCKING

source /usr/local/Ascend/ascend-toolkit/set_env.sh
source /usr/local/Ascend/nnal/atb/set_env.sh
export LD_LIBRARY_PATH=/usr/local/Ascend/ascend-toolkit/latest/opp/vendors/customize/op_api/lib/:${LD_LIBRARY_PATH}
export PATH=/usr/local/Ascend/8.5.0/compiler/bishengir/bin:$PATH

export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
export STREAMS_PER_DEVICE=32
# IP를 p 첫 번째 노드 ip로 설정
export ASCEND_MF_STORE_URL="tcp://XXXXXX:24670"

# p 노드 IP
P_IP=('XXXXX')
# D 노드 IP
D_IP=('XXXXX')


# mlapo 활성화
export SGLANG_NPU_USE_MLAPO=1
export SGLANG_USE_FIA_NZ=1
export ENABLE_MOE_NZ=1
#export SGLANG_NPU_USE_MULTI_STREAM=1

LOCAL_HOST1=`hostname -I|awk -F " " '{print$1}'`
LOCAL_HOST2=`hostname -I|awk -F " " '{print$2}'`
echo "${LOCAL_HOST1}"
echo "${LOCAL_HOST2}"

prefill

MODEL_PATH=/path/to/deepseekr1_w4a8_pertoken
for i in "${!P_IP[@]}";
do
    if [[ "$LOCAL_HOST1" == "${P_IP[$i]}" || "$LOCAL_HOST2" == "${P_IP[$i]}" ]];
    then
        echo "${P_IP[$i]}"
        export HCCL_BUFFSIZE=2600
        export HCCL_SOCKET_IFNAME=lo
        export GLOO_SOCKET_IFNAME=lo
        python -m sglang.launch_server --model-path ${MODEL_PATH}  --disaggregation-mode prefill --host ${P_IP[$i]} \
        --port 8000 --disaggregation-bootstrap-port $((8998+$i)) --trust-remote-code --nnodes 1 --node-rank 0 \
        --tp-size 16 --mem-fraction-static 0.7 --attention-backend ascend --device npu --quantization modelslim \
        --disaggregation-transfer-backend ascend --max-running-requests 32 --context-length 8192  --disable-radix-cache \
        --chunked-prefill-size -1 --max-prefill-tokens 10240 --moe-a2a-backend deepep --deepep-mode normal \
        --speculative-algorithm NEXTN --speculative-num-steps 1 --speculative-eagle-topk 1 --speculative-num-draft-tokens 2  \
        --dp-size 8 --enable-dp-attention --disable-shared-experts-fusion --dtype bfloat16
        NODE_RANK=$i
        break
    fi
done

decode

MODEL_PATH=/path/to/deepseekr1_w4a8_pertoken

for i in "${!D_IP[@]}";
do
    if [[ "$LOCAL_HOST1" == "${D_IP[$i]}" || "$LOCAL_HOST2" == "${D_IP[$i]}" ]];
    then
        echo "${D_IP[$i]}"
        export SGLANG_ENABLE_OVERLAP_PLAN_STREAM=1
        export HCCL_BUFFSIZE=900
        export SGLANG_DEEPEP_NUM_MAX_DISPATCH_TOKENS_PER_RANK=112
        export TASK_QUEUE_ENABLE=1
        export HCCL_SOCKET_IFNAME=data0.3001
        export GLOO_SOCKET_IFNAME=data0.3001
        python -m sglang.launch_server --model-path ${MODEL_PATH} --disaggregation-mode decode --host ${D_IP[$i]} \
        --port 8001 --trust-remote-code --nnodes 1 --node-rank 0 --tp-size 16 --dp-size 16 \
        --mem-fraction-static 0.8 --max-running-requests 448 --attention-backend ascend --device npu --quantization modelslim \
        --moe-a2a-backend deepep --enable-dp-attention --deepep-mode low_latency --enable-dp-lm-head \
        --cuda-graph-bs-decode 2 4 6 8 10 12 14 16 18 20 22 24 26 28 --disaggregation-transfer-backend ascend --watchdog-timeout 9000 --context-length 8192 \
        --speculative-algorithm NEXTN --speculative-num-steps 3 --speculative-eagle-topk 1 --speculative-num-draft-tokens 4 --disable-shared-experts-fusion --dtype bfloat16 --tokenizer-worker-num 4 \
        --load-balance-method round_robin
        NODE_RANK=$i
        break
    fi
done

router

python -m  sglang_router.launch_router --prefill ${P_IP}:8000 \
--decode ${D_IP}:8001 \
--host ${D_IP} --port 6688 \
--pd-disaggregation \
--health-check-interval-secs 3600 \

더 알아보기 (Learn more)