본문으로 건너뛰기

FDP SSD for LMCache — PoC 검증 계획

이 문서의 목적: 서동주님이 작성하신 FDP PoC 브랜치를 우리 사내 평가 서버(smrc)에서 빌드·실행·측정해 FDP가 LMCache 워크로드에서 실제로 효과가 있는지를 정량적으로 확인하고, 그 결과로 upstream 기여 항목을 도출하기 위한 작업 계획입니다.

작성: Nayeon (Storage SW) · 대상 독자: 팀 전체 (LMCache/FDP 사전 지식 없이 읽을 수 있게 작성)


0. 한 장 요약 (TL;DR)

  • 무엇을: LLM 추론 캐시 엔진 LMCache 가 KV 캐시를 SSD에 저장할 때, FDP SSD 기능으로 "수명이 비슷한 데이터끼리 같은 영역에 쓰기"를 적용한 PoC가 있다.
  • : 이렇게 하면 SSD 내부 가비지 컬렉션(GC) 시 불필요한 복사가 줄어 WAF(쓰기 증폭) 가 감소하고 SSD 수명·테일 레이턴시가 좋아진다는 가설.
  • 이번 작업: 이 PoC를 사내 FDP 지원 SSD 서버에서 돌려, FDP 끄고/켜고를 같은 워크로드로 비교해 WAF·p99 지연·TTFT·캐시 적중률 4개 지표로 효과를 측정한다.
  • 산출: 측정 결과 + upstream에 올릴 후속 개선 항목(파일 backend FDP 적용, placement 정책 모듈화 등) 정리.

1. 용어 정리 (먼저 읽어주세요)

용어
LMCacheLLM 서빙에서 KV 캐시를 GPU→CPU→디스크→원격으로 계층 저장/재사용하는 오픈소스 엔진. vLLM 등과 연동된다.
KV 캐시LLM이 토큰을 생성할 때 재사용하는 attention key/value 텐서. 같은 프롬프트를 다시 처리할 때 이걸 디스크에서 불러오면 연산을 건너뛸 수 있다.
FDP (Flexible Data Placement)NVMe SSD 표준 기능. 호스트(소프트웨어)가 각 쓰기를 어느 내부 영역에 둘지 힌트를 줄 수 있다. 수명이 비슷한 데이터를 같은 영역에 모으는 데 쓴다.
Placement Handle / RUHFDP에서 "데이터를 담을 내부 묶음" 단위. SSD가 제공하는 핸들 개수(N)는 보통 최대 128개로 제한된다. 소프트웨어는 쓰기마다 핸들 번호를 지정한다.
WAF (Write Amplification Factor)SSD가 실제로 NAND에 쓴 양 ÷ 호스트가 요청한 쓰기 양. 1에 가까울수록 좋다. GC가 데이터를 옮겨 쓰면 WAF가 커지고 수명이 줄어든다.
Preconditioning (사전 조건화)SSD를 깨끗한 상태가 아니라 실사용처럼 가득 찬 "지속 상태" 로 만든 뒤 측정하는 과정. 깨끗한 SSD는 GC가 거의 안 일어나 WAF 효과가 안 보이기 때문.
raw_block backendLMCache가 파일시스템을 거치지 않고 블록 디바이스에 직접 KV를 쓰는 고성능 저장 경로. io_uring_cmd(NVMe 패스스루)를 사용한다.
io_uring_cmd리눅스 비동기 I/O 인터페이스로 NVMe 명령을 직접 보내는 방식. FDP 핸들 같은 세밀한 힌트를 디바이스에 전달할 수 있다.
smrc사내 평가 서버. FDP를 지원하는 NVMe SSD가 장착되어 있다(확정).
tensormesh실제 LLM 서빙 트래픽을 재현하는 워크로드. 최종 측정 목표.
측정 harness측정을 자동으로 돌려주는 독립 실행 스크립트. 실제 서비스 스택이 아니라, 합성 KV 쓰기 패턴을 만들어 LMCache에 흘려보내고 FDP 모드별로 WAF·지연을 캡처한다. PoC에는 benchmarks/fdp_waf_stress/ 라는 자체 harness가 들어있어, 실제 LLM 트래픽 없이도 FDP off/on 비교를 돌릴 수 있다.

2. 배경 — 왜 LMCache에 FDP인가

(아래는 FDP 제안서 — 서동주/한대규님 — 내용을 정리한 것입니다.)

2.1 LMCache의 저장 I/O 특성

특성설명
대용량 I/OKV 청크 한 개가 수 MB ~ 수십 MB (모델·토큰 수에 비례)
덮어쓰기 없음한 번 쓰고 여러 번 읽는 WORM(Write Once Read Many) 패턴
순차 접근LLM의 자기회귀 특성상 앞 토큰부터 순서대로 프리픽스 캐시를 읽음

2.2 FDP SSD가 주는 이점

이점설명
호스트 주도 데이터 배치쓰기마다 어느 묶음(스트림)에 둘지 호스트가 지정
WAF 감소·내구성 향상수명이 비슷한 데이터를 같은 영역에 모아, GC 시 불필요한 내부 복사를 줄여 NAND 마모 감소
예측 가능한 지연시간GC 간섭이 줄어 p99 같은 테일 레이턴시 스파이크 완화, 멀티테넌트 간 간섭 감소
ZNS와의 차이ZNS와 달리 배치가 100% 호스트 제어는 아님. 펌웨어가 내부적으로 스트림을 섞을 수 있음

2.3 핵심 과제 — "무엇을 같은 묶음에 둘 것인가"

데이터 수명을 어떻게 분류하느냐가 관건이다. 제안서는 세 가지 배치 시나리오를 제시한다.

① 프롬프트별 배치 (Per-Prompt) 같은 프롬프트에서 나온 KV 청크들은 함께 hot/cold가 되므로 같은 묶음에 둔다.

스트림 번호 = prompt_id % 핸들수(N)

제약: 핸들 수가 제한(≤128), 다른 프롬프트가 우연히 같은 묶음에 섞일 수 있음.

② 단계 인식 배치 (Phase-aware)

  • 디코드 단계 KV = 해당 요청 동안만 쓰는 단명 데이터
  • 프리필 단계 KV = 여러 요청에 재사용되는 장수명 데이터 → 둘을 다른 스트림으로 분리.

③ vLLM 워커별 배치 (Per-Worker) Tensor Parallelism>1이면 전체 지연은 가장 느린 랭크가 결정. 워커별로 스트림을 나눠 랭크 간 성능 격리를 개선.

Worker 0 → 묶음 0, Worker 1 → 묶음 1, Worker 2 → 묶음 2, ...

2.4 I/O 인터페이스 선택지

방식장점단점
파일시스템 (write hint)LMCache 변경 최소, 기존 FS 사용FS가 스트림을 섞을 수 있음, NVMe 스트림 패싱 upstream 미반영
Raw Block (io_uring_cmd)명시적 배치 가능, NVMe 패스스루로 고성능커스텀 스토리지 엔진 필요, NVMe/커널 전문 지식 요구

3. 검증 대상 — FDP PoC 브랜치

  • 브랜치: DongDongJu/LMCache:fdp-waf-agentic-replay-poc (서동주님이 NVIDIA PoC용으로 작성)
  • 규모: dev 기준 약 39 커밋 / 95 파일
  • 구성 (사전 코드 분석 단계1에서 확인):
    1. raw_block 저장 경로 인프라 (대부분 upstream dev에 이미 반영된 기능과 동등)
    2. FDP / io_uring_cmd 코어 (핵심 3 커밋) — 위 ①②③ placement 정책 일부 포함
    3. FDP 부하/WAF 측정 harness — FDP 끄고/켜고 비교 모드(mixed/separated/no_fdp)를 갖춘 벤치 스크립트 포함

즉, 이 PoC는 "FDP를 적용하는 코드"와 "효과를 재는 측정 도구"를 함께 들고 있어, 우리 서버에서 빌드만 되면 비교 측정을 바로 돌릴 수 있는 상태다.

3.1 "무엇을 같은 묶음에 둘 것인가" — 어디까지 실제 구현됐나

2.3절의 3개 배치 시나리오가 모두 LMCache 본체에 들어있는 것은 아니다. 묶음에 쓰는 장치(통로) 와 무엇을 어느 묶음에 둘지 정하는 정책 을 나눠 보면:

항목구현 위치상태
묶음에 쓰는 통로 (핸들 번호를 실제 NVMe 쓰기 명령에 주입)LMCache backend 코어 + Rust FFI✅ 완전 구현 — "지정한 묶음에 진짜로 쓴다"가 동작
③ 워커별 정책 (Worker N → 묶음 N)LMCache backend 코어✅ backend에 내장 — 하드웨어 단에서 실제 발화
① 프롬프트별 정책 (prompt_id % N)측정 harness 전용⚠️ backend에는 없음 — harness가 묶음을 미리 정해 표시
② 단계별 정책 (프리필/디코드 분리)측정 harness 전용⚠️ backend에는 없음 — harness 우회

측정 가능성: 셋 다 효과 측정은 가능하다. WAF는 어느 계층이 묶음을 정하든 nvme smart-log로 재므로, 정책이 harness에 있어도 off/on 비교가 성립한다. 다만 ①②의 측정값은 "harness가 묶음을 정했을 때의 효과"이지 "LMCache 본체에 정책이 내장된 상태"의 값은 아니다 — 이 내장화가 5단계 upstream 작업의 핵심 빈자리다.

현재까지 파악된 빈자리 (upstream 개선 후보):

  • 파일시스템 backend의 FDP 적용은 미구현
  • placement 정책 중 prompt/phase 인식은 본체가 아닌 측정 harness에만 존재 (위 표 ①②)
  • SSD의 RUH 디스크립터 자동 조회 기능 미포함

4. 검증 계획 — 5단계

단계내용담당위치
1PoC 코드 분석 — 구조 지도, 구현 완성도 auditNayeon로컬 (완료)
2환경 audit — FDP 파라미터·toolchain·권한 수집Codexsmrc 서버 / 현재 세션
3빌드 + 동작 확인 — PoC 빌드, 회귀 테스트, FDP 경로 1회 발화 입증Codexsmrc 서버 / 현재 세션
4워크로드 측정 — FDP off vs on 정량 비교Codexsmrc 서버 / 현재 세션
5개선 도출 — 측정 기반 upstream PR 항목 정리Nayeon로컬

진행 방식: 사내 서버에서 돌리는 단계(2~4)는 복사·붙여넣기로 실행 가능한 스크립트를 미리 만들어 드리고, 실행 결과(로그/JSON)를 받아 정리합니다.

단계 2 — 환경 audit (먼저 실행)

목적: 측정에 필요한 입력값(SSD 용량, FDP 핸들 수, 쓰기 대역폭, 권한) 확정. 실행: precheck.sh 한 번 실행 → 결과 tarball 회수 (읽기 전용, 디바이스를 건드리지 않음).

수집 항목:

  • 커널/디바이스 식별 (nvme list, id-ctrl, id-ns → 용량 C)
  • FDP 파라미터 (nvme fdp configs → 핸들 수 N, fdp status, fdp stats 기준선)
  • WAF 기준선 (nvme smart-log → 누적 쓰기량)
  • toolchain (rustc/cargo/maturin/liburing — 빌드 가능 여부)
  • 권한 (raw block 접근, blkdiscard 가능 여부 — 측정 반복에 필요)

단계 3 — 빌드 + 동작 확인

PoC 빌드 → raw_block 회귀 테스트 → 작은 데이터 1회 write 후 nvme fdp stats 변화량으로 "FDP 쓰기 경로가 실제 디바이스에 도달했다" 를 입증.

단계 4 — 측정 (효과 확인의 본체)

→ 5절에서 상세.

단계 5 — 개선 도출

측정 결과로 후속 작업 분할: placement 정책 모듈화 / 파일 backend write hint 적용 / raw_block 메타데이터 통로 / 한대규님 라인과의 통합 등.


5. FDP 효과를 어떻게 측정하나 (단계 4 상세)

5.1 핵심 아이디어

같은 워크로드(tensormesh)를 FDP 끈 상태켠 상태로 각각 돌리고, 아래 4개 지표를 비교한다.

지표의미측정 방법
WAF쓰기 증폭 (낮을수록 좋음)nvme smart-logdata_units_written ÷ 호스트 쓰기량
p99 read latency읽기 테일 지연LMCache 로드 경로 타이머
TTFT첫 토큰까지 시간tensormesh harness 출력
Hit ratio캐시 적중률LMCache lookup hit ÷ total

5.1.5 측정 순서 — PoC harness 먼저, tensormesh 나중

PoC는 자체 측정 harness(benchmarks/fdp_waf_stress/)를 들고 있어, 실제 LLM 트래픽 없이도 FDP off/on WAF 비교를 한 번에 돌릴 수 있다. 반면 tensormesh(실 워크로드) 연결은 harness가 자식 LMCache를 띄우는 구조라 별도 통합 작업이 필요하다. 따라서 측정은 2단계로 나눈다:

  1. 1차 — PoC 자체 harness (먼저): --mode no_fdp / separated / mixed 로 R1/R2/R3 WAF 비교를 즉시 확보. 통합 작업 없이 FDP 효과의 1차 신호를 얻는다.
  2. 2차 — tensormesh 연결 (나중): 1차에서 효과가 확인되면, 실 워크로드(TTFT·hit ratio 포함)로 검증을 확장.

이유: 1차 harness는 통합 비용이 거의 없어 "효과가 있나/없나"를 가장 빨리 가른다. 효과가 없으면 tensormesh 통합 비용을 들이기 전에 방향을 재검토할 수 있다.

5.2 실행 순서 (Run matrix)

ID내용
R0사전 조건화: 디스크를 비운 뒤 지속 상태가 될 때까지 채움 (매 측정 전 반복)
R1기준: FDP off + tensormesh
R2FDP on (프롬프트별 배치, prompt_id % N) — 동일 시드
R3(선택) 단계 인식 배치 (프리필/디코드 분리)
R4(선택) 워커별 배치 (워커 ≥ 2)

5.3 ⚠️ 측정 파라미터는 아직 확정 전

사전 조건화 시간·채우는 양·각 run 길이·반복 횟수 같은 구체 숫자는 디바이스 사양과 시간 예산이 정해져야 계산됩니다. 임의로 정하지 않고 아래 규칙으로 산출합니다.

파라미터결정 방법입력 출처
사전 조건화 시간SSD 용량의 약 1.5~2배를 써야 지속 상태 도달 → 용량 ÷ 쓰기대역폭단계 2 (용량·대역폭)
채우는 양지속 상태 목적이면 거의 전체 용량을 채운 뒤 랜덤 덮어쓰기단계 2 (용량)
run 길이(ramp/steady)캐시 적중률·WAF 카운터가 안정될 때까지 — 1회 예비 실행으로 결정단계 4 예비 run
반복 횟수(서버 점유 가능 시간) ÷ (1 run 시간). 예산 미정이면 우선 1회시간 예산 (미정)
핸들 수 Nnvme fdp configs 의 RUH 개수단계 2

주의: 깨끗한 SSD에서 측정하면 GC가 거의 없어 WAF 차이가 안 보입니다. 반드시 사전 조건화(R0)를 거친 지속 상태에서 측정해야 합니다. (제안서 "평가 시 고려사항" 참조)

5.4 측정 결과 (예시 형태)

측정 후 채워질 표 — 현재는 자리표시입니다.

지표FDP offFDP on변화
WAF(R1)(R2)↓ ?
p99 read
TTFT
Hit ratio

결론 문장 예: "FDP on에서 WAF가 A→B로 감소, p99 read −C%."


6. 일정 · 리스크

대략 일정: 단계 1 완료. 단계 23은 서버 접속 후 11.5일, 단계 4 측정은 시간 예산에 따라 가변, 단계 5 정리 1~2일.

리스크완화책
PoC가 아직 머지 안 된 NVMe 인프라(PR #3274)에 의존해당 PR 브랜치를 중간 베이스로 끼워 빌드, 또는 일반 I/O 경로만 측정
PoC 브랜치가 최신 dev와 멀어 빌드 실패rebase / 핵심 커밋만 cherry-pick / baseline 시점으로 일시 downgrade
blkdiscard 권한 부재로 측정 반복 불가단계 2에서 권한 사전 확인, 없으면 서버 관리자에 요청
워크로드 비결정성으로 결과 노이즈동일 시드, 사전 조건화 동일화, 예산 허용 시 여러 번 평균

7. 참고

  • FDP 제안서 (서동주/한대규님): "FDP SSD for LMCache" — 본 문서 2·5절의 근거
  • LMCache raw_block 저장 경로 / NVMe FDP 관련 upstream PR: #3274 (io_uring_cmd 인프라)

문의: Nayeon (Storage SW). 단계 2 환경 audit 스크립트(precheck.sh)는 준비되어 있으니, smrc 접속 가능 시점에 공유드립니다.