본문으로 건너뛰기

FDP SSD for LMCache — 배치 전략 PoC

[!tldr] 업무 관점 takeaway LMCache KV 캐시를 어떤 기준으로 FDP 스트림에 나눌 것인가? 세 가지 전략 — prompt별, prefill/decode 단계별, TP 워커별. 핵심 도전은 "수명이 다른 데이터를 어떻게 구별하느냐"이다. 구현 경로는 Raw Block + io_uring_cmd (dspec 필드)가 명시적 배치를 위한 정석. 2026-06-15 실측 + 반복실험 재해석 (2026-06-19): R0 precondition 후 3모드 측정. separated가 host/media write 최소(-27%)지만, replay operation 수가 세 모드 동일(finish_write 105,728) → host write 감소는 FDP 확정 효과가 아닌 SMART counter artifact. WAF ratio 세 모드 ~1.016으로 동일 → "FDP가 WAF를 낮췄다" 주장 불가. Phase 1: NS/span 축소로 드라이브 steady state 만든 후 재실험 필요.


목표

LMCache 스토리지에서 FDP SSD를 활용해 수명(lifetime)이 다른 KV 캐시 스트림을 분리:

  • WAF(Write Amplification Factor) 감소 → SSD 내구성 향상
  • 멀티테넌트 환경에서 예측 가능한 I/O 성능 (GC 간섭 감소)

LMCache의 I/O 특성

특성설명
대용량 I/OKV 청크 수 MB ~ 수십 MB
덮어쓰기 없음WORM(Write Once Read Many)
순차 접근자기회귀적 특성 → 앞 토큰부터 순서대로 prefix KV 읽기

구현 인터페이스 선택지

방식장점단점
파일 시스템 (write hints)LMCache 변경 최소화FS가 스트림 혼합 가능; NVMe 스트림 패싱 미반영
Raw Block (io_uring_cmd)명시적 배치; NVMe passthru 고성능커스텀 스토리지 엔진 필요; NVMe 전문 지식 요구

io_uring_cmd가 정석. NvmeUringCmd.cdw13 (dspec 필드)에 placement handle 직접 embed.


배치 전략 3가지

1. Prompt별 배치 (Per-Prompt)

동기: KV 청크는 rolling hash 기반 prefix hash chain을 형성 → 같은 체인의 청크는 함께 hot/cold 전환.

stream = prompt_id % num_placement_handles

제약:

  • num_placement_handles 최대 128개 (FDP SSD 하드웨어 한계)
  • 다른 prompt의 청크가 같은 그룹에 매핑될 수 있음

2. 단계 인식 배치 (Phase-aware)

동기:

  • decode KV: 현재 요청 처리 중에만 사용 → 단명(short-lived)
  • prefill KV: 여러 요청에 걸쳐 재사용 가능 → 장명(long-lived)
prefill KV → 스트림 N (장명 스트림)
decode KV → 전용 또는 기본 스트림 (단명 스트림)

수명이 다른 두 유형을 분리하면 GC가 단명 스트림만 효율적으로 회수 가능.


3. TP 워커별 배치 (Per-vLLM Worker)

동기: TP > 1 환경에서 전체 스텝 지연 = max(rank_i I/O latency). FDP로 랭크 간 성능 격리 시 tail latency 감소.

워커Placement Group
Worker 0Group 0
Worker 1Group 1
Worker 2Group 2
Worker 3Group 3

평가 시 주의사항

  • 클린 상태에서 시작하면 WAF 관찰 어려움
  • sustained state로 preconditioning 후 측정해야 의미 있는 WAF 수치 확보 가능
  • 비교군: CacheLib FDP 사례 (WAF 3.5 → ~1.0) 참고


실측 결과 (2026-06-15, Stage 4)

셋업

  • R0 window-local precondition (32GiB sequential fill + random overwrite 1회) 후 3모드 실행
  • Workers 9, warmup 2회, measurement 8회, device /dev/ng0n1

WAF + Host Write 결과

ModeHost write deltaMedia write deltaWAFwrite p99
no_fdp476 GiB484 GiB1.015871.353 ms
mixed466 GiB474 GiB1.015871.290 ms
separated348 GiB354 GiB1.015883.357 ms

해석

  • separatedhost/media write volume이 가장 낮음 (no_fdp 대비 −27%), FDP lifetime 분리 효과 관측.
  • WAF ratio 자체는 세 모드 모두 약 1.016으로 거의 동일 — 이번 batch만으로 "separated가 WAF ratio를 낮췄다"는 결론은 약함.
  • separated write p99가 3.4ms로 가장 높음 → host write는 줄었지만 write tail latency 악화 → 추가 분석 필요.
  • 1차 실험(precondition 없음)에서는 mixed가 host write 최저였으나, R0 precondition 후에는 separated가 최저로 역전 → precondition이 결과에 크게 영향함을 확인.

다음 단계 (단일 batch 기준)

  • WAF ratio 차별화를 위해 더 많은 반복 실험 + 다른 precondition 조건 필요
  • write p99 악화 원인 분석 (FDP placement 오버헤드 vs. GC 패턴 변화)
  • 2차 tensormesh 통합 실험으로 TTFT·hit ratio 측정

반복실험 재해석 (2026-06-19, 72 runs)

핵심 발견

72 measurement run 반복실험에서 세 모드의 replay operation 수가 완전히 동일했다:

항목no_fdp / mixed / separated 공통
measurement run 수72
finish_write count105,728
reserve_write count105,728
prefetch count6,464
errors0

separated가 store operation을 덜 수행해서 host write가 적어진 것이 아님.

host write 감소가 FDP 효과가 아닌 이유

  1. host_write_bytes_delta = nvme smart-log Data_Units_Written 차이 (애플리케이션 logical write 합산 아님).
  2. mode별 write path는 거의 같음: no_fdp/mixed/separated 모두 use_uring_cmd=true, FDP는 placement directive(dspec)만 다름 → host write 자체를 줄이는 메커니즘이 없음.
  3. op 수가 같은데 단일 batch에서 no_fdp 476GiB / separated 348GiB (~127GiB 벌어짐)는 R0 잔여·counter capture window·controller deferred write가 delta에 섞인 측정 artifact.
  4. WAF ratio가 세 모드 ~1.016으로 동일 — 실제 GC copy가 줄었다면 separated WAF가 떨어졌어야 함.

결론

"반복실험 평균에서 separated의 host/media write delta가 낮게 관측되었지만, replay operation 수는 세 모드가 동일하고 trial별 방향도 완전히 일관되지는 않았다. host write 감소는 FDP placement로 인한 확정적 애플리케이션 write 감소라기보다 현재 측정 조건에서 관측된 controller counter 차이로 해석해야 한다."


Phase 0 — PoC 소스 검증 결과 (2026-06-19)

결론: harness·generator 수정 불필요, Phase 1이 해법

  • warmup persist: warmup→measurement 사이 내부 discard/reset 없음 → warmup write가 measurement까지 persist. 큰 warmup을 placement-consistent preconditioner로 쓰는 전략 성립.
  • WAF window: host_delta = after − after_warmup 구간만 카운트 → warmup/R0는 WAF window 바깥.
  • device churn: logical 키는 write-once지만, capacity_bytes slot-reuse로 device 물리 overwrite는 의도 설계. stress에서 ~192GiB를 1GiB window에 errors=0 → churn 충분.
  • WAF≈1의 진짜 원인: 9 worker × ~1GiB = ~8GiB window를 2TiB offset에 몰아 써도, 멀티-TB 드라이브는 다른 NAND가 비어 있어 GC가 valid copy를 거의 안 함 → WAF≈1.

Phase 1 방향

NS/span 축소로 usable capacity ≈ (harness 총 window span + 적정 OP)가 되게 만들어, measurement window의 overwrite가 valid-data GC를 유발하도록 → 드라이브 steady state에서 재실험.

게이트: precondition 후 no_fdp WAF > 1 확인 → FDP 효과 측정 가능 상태.


관련 페이지

  • [[raw_block-io_uring-cmd]] — io_uring_cmd + dspec 필드 (FDP 배관)
  • [[NVMe-FDP]] — FDP RUH/RG/PH 개념
  • [[Plugin-Pipeline]] — LMCache 코드 수정 없이 FDP 백엔드 등록하는 방법
  • [[CacheLib-FDP-사례]] — 외부 증거
  • [[WAF]] — 개선 목표 KPI