MooncakeStoreConnector 사용 가이드

MooncakeStoreConnector 사용 가이드 (MooncakeStoreConnector Usage Guide)

MooncakeStoreConnector는 MooncakeDistributedStore 를 공유 KV 캐시 풀로 사용하는 KV 캐시 커넥터입니다. prefiller와 decoder 사이에 직접 point-to-point KV 전송을 하는 MooncakeConnector 와 달리, MooncakeStoreConnector는 외부 분산 스토어로 KV 캐시를 오프로드할 수 있게 해 주고 다음을 지원합니다.

  • CPU/디스크 오프로딩: Mooncake의 전송 엔진을 통해 CPU 메모리나 디스크로 오프로드해 유효 KV 캐시 용량을 확장합니다.
  • 인스턴스 간 프리픽스 캐싱: 해시 기반 중복 제거로 여러 vLLM 인스턴스가 스토어를 통해 캐시된 KV 블록을 공유할 수 있습니다.
  • 단일 노드 및 다중 노드 배포: 독립형 KV 캐시 확장과 분리형(disaggregated) prefill-decode 설정 모두에서 동작합니다.

출처: 문서

본문

사전 준비 (Prerequisites)

Mooncake 설치 (Install Mooncake)

pip으로 mooncake를 설치하세요.

uv pip install mooncake-transfer-engine

더 자세한 설치 방법과 소스에서 빌드하는 방법은 Mooncake 공식 저장소 를 참고하세요.

Mooncake 마스터 서버 시작 (Start the Mooncake Master Server)

Mooncake 마스터는 메타데이터를 관리하고 분산 스토어를 조정합니다. vLLM을 실행하기 전에 시작하세요.

mooncake_master --port 50051

기본 포트: RPC: 50051

여러 vLLM 인스턴스가 같은 마스터 서버를 공유할 수 있습니다.

Mooncake 구성 (Configure Mooncake)

JSON 구성 파일(예: mooncake_config.json)을 만듭니다.

{
  "mode": "embedded",
  "metadata_server": "P2PHANDSHAKE",
  "master_server_address": "127.0.0.1:50051",
  "global_segment_size": "80GB",
  "local_buffer_size": "4GB",
  "protocol": "rdma",
  "device_name": "",
  "enable_offload": false
}
  • mode: 토폴로지 선택입니다. "embedded"(기본값, PR-40900 baseline)는 각 vLLM 랭크가 프로세스 내에서 global_segment_size 만큼 풀에 기여합니다. "standalone-store" 는 랭크를 순수 리퀘스터로 만듭니다. 외부 mooncake_client 프로세스가 CPU 풀과 (선택적으로) SSD 계층을 소유합니다.
  • protocol: 최상의 성능을 위해 "rdma" 를 사용하세요. "tcp" 는 폴백으로 동작합니다.
  • global_segment_size: 분산 풀에 기여하는 CPU 메모리(GPU당)입니다. embedded 모드에서는 > 0 이어야 하고 standalone-store 모드에서는 0 이어야 합니다.
  • local_buffer_size: 이 노드 자체 연산을 위한 전용 버퍼(GPU당)입니다.
  • enable_offload: true 이면 vLLM이 DirectIO 스테이징 버퍼를 할당해 큰 prefill이 소유자의 SSD 쓰기 예산을 초과하지 않도록 합니다. mooncake_master 와 외부 mooncake_client(있다면)의 --enable_offload=true 플래그와 함께 설정하세요.
  • tenant_id: 선택적 Mooncake 테넌트 네임스페이스입니다. 스토어 데이터를 공유해야 하는 프로듀서와 컨슈머는 반드시 같은 tenant id를 사용해야 합니다. 기본값: "default".

구성 경로를 환경 변수로 설정합니다.

export MOONCAKE_CONFIG_PATH=/path/to/mooncake_config.json

사용법 (Usage)

단일 노드 KV 캐시 오프로딩 (Single-Node KV Cache Offloading)

MooncakeStoreConnector를 사용해 KV 캐시를 CPU 메모리로 오프로드해 유효 캐시 크기를 확장합니다.

MOONCAKE_CONFIG_PATH=mooncake_config.json \
vllm serve meta-llama/Llama-3.1-8B-Instruct \
    --kv-transfer-config '{"kv_connector":"MooncakeStoreConnector","kv_role":"kv_both"}'

분리형 Prefill-Decode (XpYd)

분리형 prefill-decode 모드에서는 MultiConnector 를 사용해 MooncakeConnector(point-to-point KV 전송)와 MooncakeStoreConnector(공유 KV 캐시 풀)를 결합합니다. 이렇게 하면 prefiller와 decoder 사이의 직접 P2P 전송과 분산 스토어를 통한 인스턴스 간 프리픽스 캐시 공유가 모두 가능해집니다.

Prefiller 노드:

MOONCAKE_CONFIG_PATH=mooncake_config.json \
VLLM_MOONCAKE_BOOTSTRAP_PORT=50052 \
vllm serve meta-llama/Llama-3.1-8B-Instruct \
    --port 8100 \
    --kv-transfer-config '{
        "kv_connector": "MultiConnector",
        "kv_role": "kv_producer",
        "kv_connector_extra_config": {
            "connectors": [
                {
                    "kv_connector": "MooncakeConnector",
                    "kv_role": "kv_producer"
                },
                {
                    "kv_connector": "MooncakeStoreConnector",
                    "kv_role": "kv_both"
                }
            ]
        }
    }'

Decoder 노드:

MOONCAKE_CONFIG_PATH=mooncake_config.json \
VLLM_MOONCAKE_BOOTSTRAP_PORT=50053 \
vllm serve meta-llama/Llama-3.1-8B-Instruct \
    --port 8200 \
    --kv-transfer-config '{
        "kv_connector": "MultiConnector",
        "kv_role": "kv_consumer",
        "kv_connector_extra_config": {
            "connectors": [
                {
                    "kv_connector": "MooncakeConnector",
                    "kv_role": "kv_consumer"
                },
                {
                    "kv_connector": "MooncakeStoreConnector",
                    "kv_role": "kv_consumer"
                }
            ]
        }
    }'

새로 완료된 decode KV 블록도 오프로드하려면 디코더의 MooncakeStoreConnector 항목에 다음 추가 구성을 입력하세요.

decode 처리가 시작되면 컨슈머는 블록 정렬된 프롬프트 프리픽스를 확인하고 Store에서 누락된 블록을 채웁니다. 이후 저장은 새로 완료된 decode 블록을 추가합니다. 이렇게 하면 완전하고 재사용 가능한 프리픽스가 Store에 유지됩니다. 또한 MooncakeConnector 가 직접 전달한 프롬프트 KV도 포함됩니다.

{
    "kv_connector_extra_config": {
        "save_decode_cache": true
    }
}

여러 Prefill TP 크기 간 Store 공유 (Sharing one Store across multiple Prefill TP sizes)

이기종-TP 공유는 일반적으로 고정된 store_tp_size 를 사용합니다. 여러 prefiller가 서로 다른 TP 크기를 사용할 때, 최소공배수에서 파생된 공통 Store TP를 옵트인합니다.

{
    "kv_connector_extra_config": {
        "enable_store_tp_lcm": true,
        "prefill_tp_sizes": [4, 2]
    }
}

이 항목을 공유하는 모든 prefiller와 decoder는 반드시 같은 목록을 사용해야 합니다. 예시는 Store TP 4를 선택합니다. TP4 엔드포인트는 각 랭크를 하나의 Store 샤드에 매핑하고, TP2 엔드포인트는 각 랭크를 두 개의 Store 샤드에 매핑합니다. 런타임 TP 크기는 그대로 유지됩니다. "save_decode_cache": true 로 구성된 decoder는 모든 prefiller의 decode KV에 같은 Store TP를 사용합니다.

목록은 양의 정수 TP 크기를 포함할 수 있습니다. 공유하려면 Store TP가 로컬 TP 이상이면서 그 배수여야 하고, LBHNC 또는 LBNHC 로컬 KV 캐시, 그리고 기존 토폴로지와 KV-head 제약 조건이 필요합니다. Store 네임스페이스에는 attention 백엔드가 선택한 레이아웃이 포함됩니다. 서로 다른 레이아웃은 별도의 Store 항목을 사용합니다. 잘못된 형식의 목록과 지원되지 않는 엔드포인트는 격리된 rank-로컬 키 레이아웃을 사용합니다. enable_store_tp_lcm 이 없거나 false이면 prefill_tp_sizes 는 아무 효과가 없고 기존 store_tp_size 동작이 유지됩니다.

Proxy:

분리(disaggregation) 프록시는 prefiller와 decoder 노드 사이에서 요청을 라우팅합니다. MooncakeConnector 가 직접 P2P 전송에도 사용된다면 프록시 설정 세부 사항은 그 사용 가이드 를 참고하세요.

디스크 오프로딩 (Disk Offloading)

디스크 오프로딩은 standalone-store 모드에서 가장 흔히 실행됩니다. 외부 mooncake_client 프로세스가 CPU 풀과 SSD 계층을 소유하고 각 vLLM 랭크는 순수 리퀘스터가 됩니다. 이는 SSD 풀의 랭크별 중복을 피하고 DirectIO 예산 추적을 단일 프로세스에 유지합니다.

종단 간 디스크 오프로딩을 위해 세 가지가 정렬되어야 합니다.

  1. mooncake_master--enable_offload=true 로 시작됩니다.
  2. mooncake_client(소유자)가 --enable_offload=true 와 함께 MOONCAKE_OFFLOAD_FILE_STORAGE_PATH 로 SSD 경로를 지정해 시작됩니다.
  3. vLLM 쪽은 JSON 구성 파일에서 "enable_offload": true 를 설정합니다(이것은 커넥터가 읽으며 환경 변수가 아닙니다).

vLLM 쪽 mooncake_config.json 예시:

{
  "mode": "standalone-store",
  "metadata_server": "P2PHANDSHAKE",
  "master_server_address": "127.0.0.1:50051",
  "global_segment_size": 0,
  "local_buffer_size": "4GB",
  "protocol": "rdma",
  "device_name": "mlx5_0",
  "enable_offload": true
}

이 랭크를 로컬 소유자 세그먼트로 지정하려면:

export MOONCAKE_PREFERRED_SEGMENT=127.0.0.1:50053

소유자의 SSD 디렉터리, 온디스크 퇴출 정책, DirectIO 스테이징 버퍼 크기는 mooncake_client 쪽에서 표준 Mooncake 환경 변수(MOONCAKE_OFFLOAD_FILE_STORAGE_PATH, MOONCAKE_BUCKET_EVICTION_POLICY, MOONCAKE_USE_URING, MOONCAKE_OFFLOAD_LOCAL_BUFFER_SIZE_BYTES, MOONCAKE_OFFLOAD_TOTAL_SIZE_LIMIT_BYTES 등)로 제어합니다. 이는 vLLM JSON 구성과 독립적입니다.

테넌트 격리 (Tenant Isolation)

서로 다른 vLLM 배포가 분리된 Mooncake 테넌트 네임스페이스를 사용해야 한다면 Mooncake JSON 구성에서 tenant_id 를 설정하세요.

{
  "mode": "embedded",
  "metadata_server": "P2PHANDSHAKE",
  "master_server_address": "127.0.0.1:50051",
  "global_segment_size": "80GB",
  "local_buffer_size": "4GB",
  "protocol": "rdma",
  "device_name": "",
  "enable_offload": false,
  "tenant_id": "tenant-a"
}

엄격한 격리는 --enable_multi_tenants=true 로 시작된 Mooncake 마스터와 각 테넌트를 등록하는 테넌트 할당량 정책이 필요합니다. 기본이 아닌 tenant_idMooncakeDistributedStore.setup()tenant_id 파라미터를 받는 Mooncake 버전도 요구합니다. standalone-store 모드에서는 실제 스토어 클라이언트를 소유하는 프로세스이므로 외부 mooncake_client 를 일치하는 테넌트 id로 시작하세요.

환경 변수 (Environment Variables)

변수 설명 기본값
MOONCAKE_CONFIG_PATH Mooncake JSON 구성 파일 경로입니다. (필수)
VLLM_MOONCAKE_BOOTSTRAP_PORT MooncakeConnector P2P 전송용 부트스트랩 포트입니다(분리 모드 전용). 8998
MOONCAKE_PREFERRED_SEGMENT 이 랭크의 복제본을 특정 소유자 세그먼트(host:port)에 고정합니다. standalone-store 모드에서 사용합니다.
MOONCAKE_REQUESTER_LOCAL_HOSTNAME vLLM 랭크가 Mooncake에 리퀘스터로 등록하는 호스트명을 오버라이드합니다. 기본값은 랭크의 해석된 IP입니다.
VLLM_MOONCAKE_STORE_TIER_LOG 1 이면 관찰성을 위해 배치별 계층 요약(메모리 vs 디스크 적중)을 로깅합니다. disabled
VLLM_MOONCAKE_DISK_STAGING_USABLE_RATIO 리퀘스터가 단일 batch_get_into_multi_buffers 호출에서 채울 소유자 DirectIO 스테이징 버퍼의 비율입니다. 낮을수록 더 보수적인 사전 분할과 더 많은 왕복을 의미합니다. 0.9

KV 전송 설정 (KV Transfer Config)

KV 역할 옵션 (KV Role Options)

  • kv_producer: KV 캐시를 풀에 저장하는 인스턴스용입니다.
  • kv_consumer: 풀에서 KV 캐시를 로드하는 인스턴스용입니다.
  • kv_both: KV 캐시를 저장하고 로드하는 인스턴스입니다. 단일 노드 CPU 오프로딩이나 prefiller 인스턴스에 사용하세요.

kv_connector_extra_config

  • load_async (bool): 더 나은 compute-I/O 오버랩을 위해 비동기 로딩을 활성화합니다. 기본값: true.
  • lookup_async (bool): 외부 프리픽스 캐시 조회를 백그라운드 스레드에서 실행해 스케줄러 스텝을 절대 막지 않게 합니다. 진행 중인 조회가 완료될 때까지 요청을 보류하고 이후 스텝에서 재개합니다. 기본값: false.
  • lookup_rpc_port (int): ZMQ 조회 RPC 소켓용 커스텀 포트입니다. 기본값: 0.
  • cache_prefix (str): 모든 스토어 키 앞에 붙는 네임스페이스입니다. 별도 배포가 하나의 Mooncake 마스터를 공유하면서 서로 오염되지 않게 합니다. 서로 다른 프리픽스로 구성된 인스턴스는 동일한 프롬프트라도 서로의 캐시된 블록을 보지 못합니다. 프리픽스 캐시를 공유해야 하는 모든 인스턴스는 같은 값을 사용해야 합니다. 기본값: ""(프리픽스 없음; 키는 프리픽스 없는 형식과 바이트 단위로 동일).
  • save_decode_cache (bool): decode 토큰의 KV 캐시 오프로딩을 활성화합니다. kv_consumer 는 prefill 중에는 저장하지 않고, decode가 시작되면 누락된 블록 정렬 프롬프트 프리픽스를 채운 다음 완료된 decode 블록을 추가합니다. 기본값: false.
  • store_tp_size (int): 서로 다른 로컬 TP 크기를 가진 엔드포인트를 위한 공통 Store TP입니다. LBHNC 및 LBNHC 로컬 KV 캐시를 지원하며 store_tp_size >= local_tp_size 그리고 store_tp_size % local_tp_size == 0 을 요구합니다. 현재 토폴로지는 하나의 full-attention 캐시 그룹이며 PCP/DCP가 비활성화되고 크로스 레이어 블록이 비활성화됩니다. GQA와 MHA의 경우 총 KV-head 수가 store_tp_size 로 나누어 떨어져야 합니다. Store 샤드는 로컬 레이아웃에서 고정된 전역 KV-head 범위를 포함합니다. 공유 엔드포인트는 동일한 KV 캐시 레이아웃, 파이프라인 병렬 크기, Store TP를 사용합니다. Store 네임스페이스에는 레이아웃과 PP 크기가 포함됩니다. 지원되지 않는 구성은 토폴로지별 rank-로컬 네임스페이스를 사용합니다.

TP로 샤딩된 Store에서는 LBHNC/HND가 강력히 권장됩니다. LBNHC/NHD는 많은 전송 세그먼트를 만들고 PUT/GET 성능을 크게 떨어뜨릴 수 있습니다.

예를 들어 prefill TP 4, decode TP 2, KV 헤드 8개를 쓴다면 두 인스턴스 모두 store_tp_size 를 4로 설정하세요. 각 decode 랭크는 4개의 Store 샤드 중 2개를 읽고 씁니다.

총 KV 헤드가 하나인 MQA는 복제-헤드 레이아웃을 사용합니다. 지원되는 prefill TP 4 → decode TP 2 경우, 모든 랭크는 같은 rank-0 키 네임스페이스를 사용합니다. 4개의 prefill 복제본이 블록 PUT을 스트라이핑해 각 객체가 한 번만 저장되는 반면, 두 decode 랭크는 모든 블록을 GET해 로컬 KV 복제본에 넣습니다. store_tp_size 는 MQA 키에 나타나지 않으므로, PP 크기가 같으면 서로 다른 스토어 TP 크기에서 쓰인 동일한 MQA 객체가 같은 풀 항목을 공유합니다.

텐서 병렬 컬렉티브와 저정밀 연산은 TP 크기 간에 비트 단위 불변이 아니므로, 이기종-TP 재사용은 프리픽스를 decode TP 크기로 재계산할 때와 같은 그리디 출력을 보장하지 않습니다.

참고 (Notes)

프로세스 간 재현 가능한 블록 해시 (Reproducible Block Hashes Across Processes)

MooncakeStoreConnector 는 분산 스토어를 공유하는 모든 vLLM 프로세스에서 일관된 블록 해시를 요구합니다. 블록 해시는 고정 기본 시드에서 파생되는 NONE_HASH 에서 체인되므로, 기본적으로 동일한 프롬프트는 프로세스 간에 동일한 블록 해시를 만들어 추가 구성 없이 프로세스 간 프리픽스 캐시 적중을 가능하게 합니다.

예외는 --prefix-caching-hash-algo 의 비암호화 xxhash / xxhash_cbor 값으로, 이들은 프로세스별로 NONE_HASH 를 무작위로 시드합니다. 이들로 스토어를 공유하려면 PYTHONHASHSEED 가 필요합니다.

커스텀 공유 시드를 사용하려면 스토어를 공유하는 모든 인스턴스(DP 랭크, 별도 prefiller/decoder 노드, 같은 Mooncake 스토어를 가리키는 다른 모든 vLLM 프로세스)에 같은 PYTHONHASHSEED 를 설정하세요.

PYTHONHASHSEED=<shared-value> vllm serve ...

더 알아보기 (Learn more)