MoRIIOConnector 사용 가이드
MoRIIOConnector 사용 가이드 (MoRIIOConnector Usage Guide)
MoRIIOConnector 는 PD 분리 배포에서 KV 캐시 전송에 사용되는 고성능 KV 커넥터로, ROCm의 MoRI-IO 통신 라이브러리 위에 구축되어 초저오버헤드 point-to-point 통신을 제공해요.
출처: 문서
본문
사전 준비 (Prerequisites)
설치 (Installation)
Docker: MoRI는 공식 ROCm vLLM 이미지 vllm/vllm-openai-rocm:nightly 에 포함되어 있습니다.
수동 설치: MoRI wheel은 다음으로 설치할 수 있어요.
pip install amd_mori
자세한 내용은 Dockerfile.rocm_base 또는 MoRI를 소스에서 빌드하는 방법은 공식 MoRI 저장소 를 참고하세요.
적절한 NIC userspace 라이브러리 설치에 대한 지침은 NIC userspace 라이브러리 설치 를 참고하세요.
기본 사용법 (단일 호스트)
먼저 프록시를 시작하세요. 프로듀서와 컨슈머 인스턴스는 프록시에 도달할 수 있을 때까지 등록을 재시도합니다.
프로듀서 (prefiller) 구성
KV 캐시를 생성하는 prefiller 인스턴스를 시작합니다.
# Prefill instance (GPU 0-3)
export VLLM_ROCM_USE_AITER=1
export CUDA_VISIBLE_DEVICES=0,1,2,3
export HIP_VISIBLE_DEVICES=0,1,2,3
vllm serve Qwen/Qwen3-235B-A22B-FP8 \
-tp 4 \
--port 20005 \
--gpu-memory-utilization 0.9 \
--kv-transfer-config '{
"kv_connector": "MoRIIOConnector",
"kv_role": "kv_producer",
"kv_connector_extra_config": {
"proxy_ip": "127.0.0.1",
"proxy_ping_port": "36367",
"http_port": "20005",
"handshake_port": "6301",
"notify_port": "6105"
}
}'
컨슈머 (decoder) 구성
KV 캐시를 소비하는 decoder 인스턴스를 시작합니다.
# Decode instance (GPU 4-7)
export VLLM_ROCM_USE_AITER=1
export CUDA_VISIBLE_DEVICES=4,5,6,7
export HIP_VISIBLE_DEVICES=4,5,6,7
vllm serve Qwen/Qwen3-235B-A22B-FP8 \
-tp 4 \
--port 40005 \
--gpu-memory-utilization 0.9 \
--kv-transfer-config '{
"kv_connector": "MoRIIOConnector",
"kv_role": "kv_consumer",
"kv_connector_extra_config": {
"proxy_ip": "127.0.0.1",
"http_port": "40005",
"proxy_ping_port": "36367",
"handshake_port": "7301",
"notify_port": "7501"
}
}'
프록시 서버 (Proxy server)
프록시는 프로듀서와 컨슈머 인스턴스 앞에서 들어오는 요청을 그들에게 라우팅합니다. vllm-router 가 권장되는 프록시이며 수동으로 설치하거나 Docker 컨테이너로 실행할 수 있습니다. 아래 36367 포트는 각 vLLM 인스턴스에 구성된 proxy_ping_port 입니다.
Docker:
docker run \
--network host \
vllm/vllm-router:nightly \
vllm-router \
--vllm-pd-disaggregation \
--kv-connector moriio \
--vllm-discovery-address "0.0.0.0:36367"
수동 설치:
pip install vllm-router
vllm-router \
--vllm-pd-disaggregation \
--kv-connector moriio \
--vllm-discovery-address "0.0.0.0:36367"
또는 vLLM에 포함된 참조 구현 프록시를 사용할 수도 있어요.
cd <path_to>/vllm
pip install quart aiohttp msgpack
python examples/disaggregated/disaggregated_serving/moriio_toy_proxy_server.py
구성 (Configuration)
커넥터는 애플리케이션 레벨과 전송 레벨의 두 가지 수준으로 구성됩니다.
애플리케이션 레벨 구성 (Application-level configuration)
모드: MoRI는 WRITE와 READ의 두 가지 작동 모드가 있습니다.
- WRITE 모드에서 프로듀서는 매 레이어 이후 계산된 KV 블록을 컨슈머의 메모리로 적극적으로 푸시합니다.
- READ 모드에서 컨슈머는 블록이 준비되었음을 통지받는 즉시 프로듀서에서 KV 블록을 한 번에 모두 풀합니다.
기본적으로 WRITE 모드가 사용됩니다. READ 모드는 --kv-transfer-config.kv_connector_extra_config.read_mode true 로 구성할 수 있어요.
컨트롤 플레인 구성: MoRI는 RDMA/xGMI로 KV 바이트를 이동하지만, 프로듀서와 컨슈머는 핸드셰이크, 블록 ID 교환, 라이브니스, 완료 신호를 위한 대역 외(out-of-band) TCP 채널도 필요합니다. 이 키들은 kv_connector_extra_config 아래에 있습니다.
proxy_ip: prefiller와 decoder 앞에 있는 분리 프록시/라우터의 IP 주소입니다. 각 vLLM 인스턴스는 등록과 하트비트 전송에 이를 사용해 프록시가 들어오는 요청을 어디로 라우팅할지 알게 합니다.proxy_ping_port: 프록시가 인스턴스 하트비트와 등록 메시지를 수신하는proxy_ip의 TCP 포트입니다. 죽은 vLLM 인스턴스를 감지하고 라우팅 테이블을 최신으로 유지하는 데 사용됩니다.http_port: 이 vLLM 인스턴스가 OpenAI 호환 API를 노출하는 HTTP 포트입니다. 프록시는 이 포트를 등록하고 인스턴스를 선택한 다음 사용자 요청을 이 포트로 전달합니다.handshake_port: prefiller와 decoder 간의 일회성 MoRI 엔진 핸드셰이크에 사용되는 TCP 포트입니다. 양쪽은 어떤 KV 전송이 일어나기 전에 여기서 RDMA 엔진 디스크립터를 교환합니다.notify_port: prefiller와 decoder 간의 제어 및 동기화 메시지에 사용되는 TCP 포트입니다. 두 모드에서 다르게 사용됩니다.- WRITE 모드:
- 블록 할당(Block allocation): decoder가 prefiller에게 자체 블록 id를 알려 prefiller가 계산된 KV 블록을 decoder 인스턴스의 올바른 위치에 푸시할 수 있게 합니다.
- 완료(Completion): 모든 블록이 전송되면 prefiller가 decoder에게 블록을 안전하게 사용할 수 있음을 통지합니다.
- READ 모드:
- 완료(Completion): decoder가 prefiller에서 모든 블록을 읽으면 prefiller에게 통지해 KV 캐시 블록을 해제하게 합니다.
- WRITE 모드:
참고:
notify_port는 기본 포트로 사용됩니다. 인스턴스 내 각 (DP rank, TP rank) 쌍은notify_port + offset을 사용하며 offset은 랭크에 기반합니다.notify_port부터 시작하는 범위가 호스트에서 비어 있는지 확인하세요.
전송 구성 (Transport configuration)
MoRI에는 RDMA와 xGMI 두 가지 전송 백엔드가 있습니다. --kv-transfer-config.kv_connector_extra_config.backend $BACKEND 로 백엔드를 선택할 수 있으며, $BACKEND 는 rdma 또는 xgmi 입니다. RDMA가 기본 백엔드이며 다중 노드 배포에서 사용해야 합니다.
각 백엔드의 구성 옵션은 다음과 같습니다.
RDMA 백엔드
qp_per_transfer: 전송당 사용되는 RDMA 큐 페어(QP) 수입니다. QP가 많을수록 단일 전송을 여러 QP에 스트라이핑해 NIC 동시성을 높일 수 있지만 더 많은 RDMA 리소스를 소모합니다.post_batch_size: 하나의ibv_post_senddoorbell에 배치되는 RDMA 워크 리퀘스트(WR) 수입니다. 기본값은 -1로 백엔드 기본값을 의미합니다. 더 큰 배치는 WR당 posting 오버헤드를 줄입니다.num_workers: MoRI가 전송 완료를 post하고 poll하는 데 사용하는 워커 스레드 수입니다.
고급 사용자는 MORI_IO_QP_MAX_SEND_WR, MORI_IO_QP_MAX_CQE 같은 환경 변수로 MoRI 자체도 구성할 수 있습니다. 이들은 MoRI 라이브러리 변수이며 vLLM 자체의 VLLM_MORIIO_* 설정과는 별개입니다. 자세한 내용은 MoRI 저장소 를 참고하세요.
xGMI 백엔드
prefiller와 decoder가 같은 물리 호스트에서 실행될 때 xGMI를 사용하면 전송이 AMD GPU 패브릭을 통해 이루어져 NIC를 완전히 건너뜁니다. 현재 MoRI 전용 환경 변수로만 구성됩니다. MoRI 저장소 를 참고하세요.
다중 노드 배포 (Multi-node deployment)
아래 예시는 두 노드에서 1P1D 배포를 실행하는 방법을 보여줍니다. prefill 인스턴스와 같은 노드에서 프록시를 실행합니다.
두 노드 모두에서
# Set on both nodes before running any command
export PREFILL_IP=<node1-ip>
export DECODE_IP=<node2-ip>
노드 1에서
프록시 서버 에 설명된 대로 먼저 프록시를 시작한 다음 prefill 인스턴스를 시작합니다.
docker run \
--name moriio-prefill \
--init --network host --ipc host --privileged \
--security-opt seccomp=unconfined \
--ulimit memlock=-1 --ulimit stack=67108864 --shm-size 256G \
--group-add video --group-add render \
--device /dev/kfd --device /dev/dri --device /dev/infiniband \
-e VLLM_ROCM_USE_AITER=1 \
vllm/vllm-openai-rocm:nightly \
deepseek-ai/DeepSeek-R1-0528 \
--port 8100 \
--tensor-parallel-size 8 \
--enable-expert-parallel \
--gpu-memory-utilization 0.8 \
--trust-remote-code \
--kv-transfer-config '{
"kv_connector": "MoRIIOConnector",
"kv_role": "kv_producer",
"kv_connector_extra_config": {
"proxy_ip": "'"${PREFILL_IP}"'",
"proxy_ping_port": "36367",
"http_port": "8100",
"handshake_port": "6301",
"notify_port": "61005"
}
}'
노드 2에서
decode 인스턴스:
docker run \
--name moriio-decode \
--init --network host --ipc host --privileged \
--security-opt seccomp=unconfined \
--ulimit memlock=-1 --ulimit stack=67108864 --shm-size 256G \
--group-add video --group-add render \
--device /dev/kfd --device /dev/dri --device /dev/infiniband \
-e VLLM_ROCM_USE_AITER=1 \
vllm/vllm-openai-rocm:nightly \
deepseek-ai/DeepSeek-R1-0528 \
--port 8200 \
--tensor-parallel-size 8 \
--gpu-memory-utilization 0.8 \
--trust-remote-code \
--enable-expert-parallel \
--kv-transfer-config '{
"kv_connector": "MoRIIOConnector",
"kv_role": "kv_consumer",
"kv_connector_extra_config": {
"proxy_ip": "'"${PREFILL_IP}"'",
"proxy_ping_port": "36367",
"http_port": "8200",
"handshake_port": "6301",
"notify_port": "61005"
}
}'
트러블슈팅 (Troubleshooting)
availDevices.size() > 0 assertion 실패
문제: vLLM이 다음 로그와 함께 실행에 실패합니다.
libibverbs: Warning: Driver bnxt_re does not support the kernel ABI of 6 (supports 1 to 1) for device /sys/class/infiniband/rdma4
...
ker: /app/mori/src/io/rdma/backend_impl.cpp: mori::io::RdmaManager::RdmaManager(const RdmaBackendConfig, application::RdmaContext *): Assertion `availDevices.size() > 0' failed.
해결책: 설치된 RDMA userspace 라이브러리가 호스트에 설치된 드라이버 및 펌웨어 버전과 일치하지 않습니다. RDMA 커널 모듈과 펌웨어 버전에 해당하는 NIC userspace 라이브러리를 설치해야 합니다. 자세한 내용은 NIC userspace 라이브러리 설치 를 참고하세요.
부록 (Appendix): NIC userspace 라이브러리 설치
RDMA로 MoRI를 실행하려면 환경에 관련 커널 모듈 및 펌웨어 버전과 일치하는 필요한 RDMA userspace 라이브러리가 설치되어 있어야 합니다.
공식 이미지 vllm/vllm-openai-rocm:nightly 에는 다음 NIC 및 커널 모듈 버전에 대한 userspace 라이브러리가 사전 설치되어 있습니다.
- AINIC (AMD Pensando Pollara): 버전
1.117.5-a-77,libionic1=54.0-187-1을 포함하며ionic-dkms=26.03.3.001로 테스트됨. - Thor2 (Broadcom): 버전
235.2.86.0,bnxt-en-dkms=1.10.3.235.2.86.0,bnxt-re-dkms=235.2.86.0로 테스트됨.
자세한 내용은 Dockerfile.rocm 을 참고하세요. 위에 나열된 것과 다른 NIC, 커널 모듈, 및/또는 FW를 사용하는 사용자는 공급업체의 자체 설치 지침을 참조하세요.