本文档将架构设计中的 8 个 Phase 展开为可按日执行的详细任务。 每个任务标注:优先级、预估工时、前置依赖、产出文件、可验证标准。
在正式编码前,需验证三个关键假设:
| 验证项 | 方法 | 阻塞 Phase |
|---|---|---|
RDMAS v0.1.0 tag 可编译 + pyo3-connector feature 存在 |
cargo build 直接依赖 git tag |
P4 |
LMCache key 的 chunk_hash 格式可被 Router 用 token IDs 复现 |
手动测试:LMCache key → 提取 chunk_hash → 与 XXH64(token_chunk) 比对 | P1, P6 |
vLLM/SGLang tokenizer.json 可获得并可通过 tokenizers crate 加载 |
实际下载模型 tokenizer 文件并调用 encode | P6 |
验证通过后,确认版本锁定:
- RDMAS git tag:
v0.1.0 - LMCache git tag:
v0.1.0(确认后填入) - Rust MSRV: 1.80+
| Phase | 名称 | Crate | 工时 |
|---|---|---|---|
| P0 | 开工前 spike(版本验证 + hash 对齐) | — | 2 天 |
| P1 | Director 核心数据结构 | rdmas-director |
5 天 |
| P2 | Director gRPC 服务 | rdmas-director |
5 天 |
| P3 | Router Python 原型 | 独立 Python | 2.5 天 |
| P4 | Connector Director 集成 | rectifiers-connector |
8 天 |
| P5 | Orchestrator 编排层 | rdmas-orchestrator |
6 天 |
| P6 | Router Rust 生产化 | rdmas-router |
6 天 |
| P7 | 集成测试 | 全部 | 5 天 |
| P8 | 压测 + 文档 | 全部 | 5 天 |
总计:约 44.5 个工作日(~9 周)(含 P0 spike 2 天)
P1 ──→ P2 ──→ P3 ──→ P4 ──→ P5 ──→ P6 ──→ P7 ──→ P8
│ │ │
└── 验证 P1/P2 └── 需要 Director gRPC 就绪
P3(Python 原型)可以在 P2 完成后立即并行启动,验证 Director 的正确性,不阻塞后续 Phase。 P4、P5 可部分并行(分属不同 crate)。
目标:实现 PrefixIndex、ContextIndex、BlockEntry 以及 InstanceRegistry 的内存数据结构,含并发安全、LRU 淘汰、单元测试。
前置依赖:无(纯 Rust 数据结构,不依赖 RDMAS)
- 产出文件:
crates/rdmas-director/Cargo.tomlcrates/rdmas-director/src/lib.rs- 根
Cargo.toml添加 workspace member
- 内容:创建 workspace、Cargo.toml 依赖声明(
dashmap、xxhash-rust、tokio、serde) - 验证:
cargo build -p rdmas-director成功
- 产出文件:
crates/rdmas-director/src/types.rs
- 内容:
pub type NodeId = String; pub type InstanceId = String; pub struct ModelContext { pub tenant_id: String, pub model_name: String, pub block_size: u32, pub additional_salt: String, } pub struct BlockEntry { pub node_ids: Vec<NodeId>, pub access_count: AtomicU64, pub last_access: AtomicU64, }
- 验证:
cargo test通过(含 Hash/Eq derive 测试)
- 产出文件:
crates/rdmas-director/src/context_index.rs
- 内容:
ContextIndex结构体:entries: DashMap<u64, BlockEntry>BlockEntry使用RwLock<Vec<NodeId>>(非不可变 Vec)以确保report_store/report_remove的并发安全fn report_store(&self, block_hash: u64, node_id: NodeId)— 插入或追加,获取 write lockfn report_remove(&self, block_hash: u64, node_id: NodeId)— 获取 write lock 移除fn query(&self, block_hashes: &[u64]) -> HashMap<NodeId, u32>— 获取 read lock 读取,不重复计数fn evict_lru(&self, max_entries: usize)— LRU 淘汰
- 边界情况处理:
- 同一个 block_hash 被多次 report_store → node_ids 去重
- report_remove 后 node_ids 为空 → 删除整个 entry
- query 空列表 → 返回空 HashMap
- 验证:
- 单元测试:单 block 插入查询、多 block 聚合、并发插入(多线程)
cargo test -p rdmas-director -- context_index
- 产出文件:
crates/rdmas-director/src/prefix_index.rs
- 内容:
PrefixIndex结构体:contexts: DashMap<ModelContext, ContextIndex>fn get_or_create_context(&self, ctx: ModelContext) -> Arc<ContextIndex>— 按 ModelContext 隔离fn report_store(&self, ctx: &ModelContext, block_hash: u64, node_id: NodeId)fn query(&self, ctx: &ModelContext, block_hashes: &[u64]) -> HashMap<NodeId, u32>fn get_stats(&self, ctx: &ModelContext) -> IndexStats— hit_rate 等统计
- 统计结构
IndexStats:pub struct IndexStats { pub total_blocks: usize, pub hit_rate: f64, // 近期查询命中率(滑动窗口) pub prefill_queue_depth: u32, // 注册的 prefill worker 数 pub decode_queue_depth: u32, // 注册的 decode worker 数 }
- 验证:单元测试验证多 Context 隔离、统计准确性
- 产出文件:
crates/rdmas-director/src/registry.rs
- 内容:
pub struct InstanceRegistry { instances: DashMap<InstanceId, InstanceInfo>, } pub struct InstanceInfo { pub instance_id: InstanceId, pub role: InstanceRole, // Prefill / Decode / Both pub node_id: NodeId, // 附近 RDMAS 节点 pub rpc_endpoint: String, // vLLM HTTP 地址 pub dp_rank: u32, pub last_heartbeat: AtomicU64, }
- 方法:
fn register(&self, info: InstanceInfo)— 注册实例fn deregister(&self, instance_id: &str)— 注销fn heartbeat(&self, instance_id: &str)— 更新心跳fn get_nearby_prefills(&self, node_id: &str) -> Vec<InstanceId>— 按 node 查询 prefillfn get_nearby_decodes(&self, node_id: &str) -> Vec<InstanceId>— 按 node 查询 decodefn get_endpoint(&self, instance_id: &str) -> Option<String>— 获取 HTTP 地址fn get_pd_counts(&self) -> (u32, u32)— 当前 P/D 数量fn evict_stale(&self, timeout_ms: u64)— 心跳超时清理
- 验证:
- 单元测试:注册/查询/心跳/注销/超时清理
cargo test -p rdmas-director -- registry
目标:定义 Protobuf 接口,实现 gRPC server,暴露 Query / ReportStore / ReportRemove / Register / Deregister RPC。
前置依赖:P1 完成(依赖 PrefixIndex + InstanceRegistry)
- 产出文件:
proto/director.proto
- 内容:按架构设计 §3.4 定义
Directorservice 及所有 message - 验证:
cargo build确认 tonic-build 生成代码无报错
- 产出文件:
crates/rdmas-director/src/server.rscrates/rdmas-director/src/main.rs(独立二进制入口)
- 内容:
- tonic server 启动,监听
0.0.0.0:9200 DirectorService结构体持有Arc<PrefixIndex>+Arc<InstanceRegistry>- 各 RPC handler 为
unimplemented!()占位
- tonic server 启动,监听
- 验证:
grpcurl -plaintext localhost:9200 list能看到 service
- 产出文件:
crates/rdmas-director/src/report.rs
- 内容:
ReportStore: 解析ReportStoreRequest,调用PrefixIndex::report_store()ReportRemove: 调用PrefixIndex::report_remove()- 参数校验:empty node_id / block_hash 返回
InvalidArgument
- 验证:用
grpcurl发送真实请求,检查 PrefixIndex 内部状态
- 产出文件:
crates/rdmas-director/src/query.rs
- 内容:
Query: 接收 Router 预先计算的block_hashes,直接查 PrefixIndex → InstanceRegistry → 组装QueryResponse- 注意:Director 不计算 block hashes — Router 预先计算后通过
QueryRequest.block_hashes发送
- 验证:
- 预先插入测试数据 → Query 返回正确命中
- 空 token_ids → 返回空 hits
cargo test -p rdmas-director -- query
- 产出文件:
- 更新
crates/rdmas-director/src/registry.rs(gRPC handler 部分)
- 更新
- 内容:
Register: 校验重复注册、解析 role、写入 InstanceRegistryDeregister: 移除实例Heartbeat: 更新last_heartbeat
- 验证:注册 → 心跳 → 超时清理 → 注销,完整生命周期测试
- 新增文件:
crates/rdmas-director/tests/integration_test.rs
- 内容:
- 启动 Director server → gRPC client 连接 → 完整流程:Register 两个 P + 两个 D → ReportStore 若干 block → Query 返回正确 hits
- 健康检查 endpoint:
grpc.health.v1.Health/Check
- 验证:
cargo test -p rdmas-director --test integration_test全部通过
目标:用 Python FastAPI 实现最简 Router,验证 Director 的正确性和缓存感知调度的效果。不追求性能,只验证功能。
前置依赖:P2 完成(Director gRPC 可用)
- 产出文件:
prototypes/router-py/requirements.txtprototypes/router-py/main.py
- 依赖:
fastapi,uvicorn,grpcio/grpcio-tools,httpx,transformers - 验证:
python main.py启动成功
- 产出文件:
prototypes/router-py/director_client.py
- 内容:
- 加载 Director proto → 生成 Python stub
DirectorClient类封装query(),report_store(),report_remove()
- 验证:连上 P2 的 Director server,调用
query()返回结果
- 产出文件:
prototypes/router-py/router.py
- 内容:
- tokenize(调 vLLM 的
/tokenizeAPI 或用transformers) - 计算 block hashes
- 调 Director.query()
- 简单决策:选
matched_blocks最多的 node → 选该 node 的第一个 worker - httpx 转发到 worker
- tokenize(调 vLLM 的
- 验证:手动 curl 发送 prompt,观察请求被转发到正确的 worker
- 产出文件:
prototypes/router-py/stream.py
- 内容:httpx SSE 流式读取 → StreamingResponse 透传
- 验证:端到端测试脚本
prototypes/router-py/test_e2e.py
- 产出文件:
prototypes/router-py/VERIFICATION.md
- 内容:
- Director 索引更新及时性
- 缓存命中 vs 未命中时的路由差异
- 多 worker 场景下的调度分布
- 发现的问题和改进点
- 可选:如果 vLLM 环境不可用,用 mock worker(返回固定 token stream)替代
目标:在 RDMAS 已有的 lmcache-connector 中织入 Director 上报逻辑。submit_batch_set 自动调 report_store,submit_batch_delete 自动调 report_remove。
注意:RDMAS 的
lmcache-connector是上游项目。本 Phase 的实现方式为:在rectifiers-connectorcrate 中 wrap 上游 connector 并添加 Director 集成;或者向上游提 PR 添加 feature flag。
前置依赖:P2 完成(Director gRPC 可用),需 RDMAS 仓库可编译
- 产出文件:
crates/rectifiers-connector/Cargo.toml(依赖rdmasgit dep)
- 内容:
- 在
Cargo.toml中声明rdmas = { git = "https://github.com/ipconfiger/rdmas", tag = "v0.1.0", features = ["pyo3-connector"] } - 验证能编译通过、link 到 libibverbs
- 在
- 验证:
cargo build -p rectifiers-connector成功
- 产出文件:
crates/rectifiers-connector/src/director_client.rs
- 内容:
- tonic gRPC client 连接 Director
:9200 DirectorClient封装report_store,report_remove- 连接重试 + 超时处理
- tonic gRPC client 连接 Director
- 验证:单元测试 mock Director server
- 产出文件:
crates/rectifiers-connector/src/connector.rs
- 内容:
- 阶段 1(submit_batch_set):记录 pending 元数据
future_id → (node_id, block_hashes, ctx),不立即上报 - 阶段 2(drain_completions):仅在
comp.ok == true时调director_client.report_store() report_store调用为 tokio::spawn fire-and-forget,失败时 tracing::warn 记录
- 阶段 1(submit_batch_set):记录 pending 元数据
- 关键保证:RDMA 写入成功后 Director 才知道该 block 存在,避免 phantom cache hits
- 产出文件:
crates/rectifiers-connector/src/config.rs
- 内容:
- 同 D4-3,
submit_batch_delete调report_remove - 配置结构:
pub struct RectifiersConfig { pub director_addr: Option<String>, // "127.0.0.1:9200" pub node_id: String, pub tenant_id: String, pub model_name: String, pub block_size: u32, }
- 从 LMCache
adapter_paramsJSON 解析配置
- 同 D4-3,
- 验证:集成测试:配置 director_addr → 调 submit_batch_set → 验证 Director 收到 report
- 产出文件:
crates/rectifiers-connector/src/lib.rs(PyO3 entrypoint)
- 内容:
- 导出增强版
RDMANativeConnectorpyclass - 支持
adapter_params中的director_addr字段 - 端到端测试:Python 侧调
submit_batch_set→ Rust 侧走完整链路 → Director 收到上报
- 导出增强版
- 验证:Python 测试脚本 +
cargo test -p rectifiers-connector
目标:实现 auto_tune_loop 决策循环、vLLM reconfigure 调用、stats 收集与暴露。
前置依赖:P2 完成(Director gRPC 可用)
- 产出文件:
crates/rdmas-orchestrator/Cargo.tomlcrates/rdmas-orchestrator/src/lib.rscrates/rdmas-orchestrator/src/main.rs
- 依赖:
rdmas-director(local path dep),tokio,reqwest,serde - 验证:
cargo build -p rdmas-orchestrator
- 产出文件:
crates/rdmas-orchestrator/src/stats.rs
- 内容:
StatsCollector结构体,周期性(30s)调 Director gRPC 获取 stats- 采集指标:
pub struct SystemStats { pub hit_rate: f64, pub prefill_count: u32, pub decode_count: u32, pub prefill_queue_depth: u32, pub decode_queue_depth: u32, }
- 验证:mock Director → 验证 stats 采集正确
重要:vLLM 无运行时角色切换 HTTP API。Orchestrator 通过 K8s API 调整独立 Prefill/Decode Deployment 副本数。
- 产出文件:
crates/rdmas-orchestrator/src/decision.rs
- 内容:
pub struct AutoTuner { config: AutoTuneConfig, director: DirectorClient, k8s_client: K8sClient, } impl AutoTuner { async fn evaluate(&self, stats: &SystemStats) -> Option<Action> { if stats.hit_rate < self.config.hit_rate_threshold_up && stats.prefill_count < self.config.max_prefill { Some(Action::ScalePrefillUp) } else if stats.hit_rate > self.config.hit_rate_threshold_down && stats.decode_count < self.config.max_decode { Some(Action::ScaleDecodeUp) } else { None } } async fn execute(&self, action: Action) -> Result<()> { match action { Action::ScalePrefillUp => { self.k8s_client.scale("vllm-prefill", +1).await?; self.k8s_client.scale("vllm-decode", -1).await?; } Action::ScaleDecodeUp => { self.k8s_client.scale("vllm-decode", +1).await?; self.k8s_client.scale("vllm-prefill", -1).await?; } } Ok(()) } }
- hysteresis 防震荡:连续 3 次评估都触发才执行切换
- 验证:单元测试覆盖各种 stats 组合 → 验证决策正确性
- 产出文件:
crates/rdmas-orchestrator/src/k8s.rs
- 内容:
K8sClient封装 K8s API → 调整 Deployment replica 计数- 扩缩前校验:不低于
min_prefill/min_decode,不超过max_prefill/max_decode - 支持 dry-run 模式(mode A: 纯建议,不执行)
- 新 Pod 启动后自动通过 Connector 调 Director.Register(),无需 Orchestrator 介入
- 验证:mock K8s API server → 验证 scale 请求格式正确
- 产出文件:
proto/orchestrator.proto
- 内容:
GetPDRatio,SetPDRatio,GetRecommendationRPC - 实现:读取 Director InstanceRegistry 的 P/D 计数
- 验证:grpcurl 调用
- 产出文件:
crates/rdmas-orchestrator/src/config.rs
- 内容:
- JSON 配置文件解析(
rectifiers_config.json) - tracing 结构化日志:决策日志包含 reason + before/after stats
- JSON 配置文件解析(
- 验证:修改配置 → 重启生效 / SIGHUP 热加载
目标:用 Rust 重写 P3 的 Python 原型,实现 tokenizer 集成、多因素决策、HTTP dispatch、SSE stream。
前置依赖:P2 完成,P5 完成(需 Director + Orchestrator gRPC 就绪)
- 产出文件:
crates/rdmas-router/Cargo.tomlcrates/rdmas-router/src/main.rs
- 依赖:
axum,rdmas-director(local path dep),tokenizers,reqwest,xxhash-rust - 验证:
cargo build -p rdmas-router成功,/health返回 200
- 产出文件:
crates/rdmas-router/src/tokenize.rs
- 内容:
- 加载
tokenizer.json(从 HuggingFace model repo 下载或本地路径) TokenizerService结构体:pub struct TokenizerService { tokenizer: tokenizers::Tokenizer, block_size: u32, } impl TokenizerService { pub fn encode(&self, prompt: &str) -> Vec<u64> { ... } pub fn compute_block_hashes(&self, token_ids: &[u64]) -> Vec<u64> { token_ids.chunks(self.block_size as usize) .map(|c| xxhash_rust::xxh3::xxh3_64(c)) .collect() } }
- 加载
- 错误处理:tokenizer 未加载 → 启动失败,明确报错
- 验证:单元测试验证 encode + hash 结果与 Python transformers 一致
- 产出文件:
crates/rdmas-router/src/director.rs
- 内容:
- tonic gRPC client 连接 Director
:9200 - 连接池 + 健康检查
- tonic gRPC client 连接 Director
- 验证:集成测试连 P2 的 Director server
- 产出文件:
crates/rdmas-router/src/decision.rs
- 内容:
- 将 §5.3 的
select_best_worker()算法从原型翻译为正式实现 - 增加:worker 负载追踪(滑动窗口 active_requests 计数)
- 增加:超时降级(Director 超时 → 随机选一个可用 worker)
- 将 §5.3 的
- 验证:单元测试覆盖各种 hits 组合
- 产出文件:
crates/rdmas-router/src/proxy.rscrates/rdmas-router/src/stream.rs
- 内容:
POST /v1/chat/completionshandler- 请求解析 → tokenize → hash → Director query → 决策 → reqwest 转发
- SSE stream 透传(
axum::response::Sse) - OpenAI 兼容 API 格式(
choices[0].delta.content) - 错误映射:Director 超时 → 503,无可用 worker → 503
- 验证:curl 发送请求 → 收到 SSE token stream
- 产出文件:
crates/rdmas-router/src/config.rs
- 内容:
- JSON 配置文件:director_addr, tokenizer_path, block_size, listen_addr
- tracing span:
request_id→tokenize→director_query→decision→dispatch→stream - metrics:request_count, hit_rate, dispatch_latency_histogram
- 验证:
/metrics暴露 Prometheus 指标
目标:全部子系统联调,含 mock RDMAS 节点和 mock vLLM worker,验证完整数据流。
前置依赖:P1-P6 全部完成
- 产出文件:
tests/mock_rdmas.rs
- 内容:
- 实现
KvEnginetrait 的 mock(内存 HashMap 后端) - 模拟 ControlPlane gRPC server(Discover / Heartbeat)
- 实现
- 验证:mock 可被 Connector 作为
KvEngine使用
- 产出文件:
tests/mock_vllm.rs
- 内容:
- HTTP server 模拟 vLLM OpenAI API
/tokenize→ 返回 mock token_ids/generate→ 返回固定 SSE token stream/admin/reconfigure→ 接受角色切换请求
- 验证:Router 能成功 dispatch 到 mock
- 产出文件:
tests/e2e_test.rs
- 测试场景:
- 冷启动:无缓存 → Router dispatch 到 prefill → prefill 写入 RDMAS → Connector 上报 Director → Director 索引更新
- 热缓存命中:相同 prompt 再次请求 → Director 返回 high hits → Router dispatch 到 decode → decode 从 RDMAS 读取 KV cache
- P:D 动态切换:模拟 hit_rate 下降 → Orchestrator 触发 reconfigure → 一个 D 转为 P → 验证 Director 注册更新
- Worker 故障:一个 worker 不可用 → Router 降级到次优 worker → 请求仍然完成
- 多 tenant 隔离:不同 tenant_id 的 model context 不互相干扰
- 验证:
cargo test --test e2e_test全部通过
- 产出文件:
tests/fault_test.rs
- 测试场景:
- Director 宕机重启 → Router 重连 + 请求恢复
- RDMAS 节点网络分区 → Connector 超时处理
- Orchestrator 误判 → hysteresis 防止震荡
- 大量并发注册 → InstanceRegistry 竞态安全
- 验证:所有故障场景有预期行为(非 panic)
目标:性能基准测试、LMCache 真实集成验证、部署文档、最终交付。
前置依赖:P7 完成
- 产出文件:
benches/director_bench.rsbenches/router_bench.rs
- 内容:
- Director: 100 万 block 索引 → Query 延迟 P50/P99
- Router: tokenize + query + decision → 端到端延迟(不含模型推理)
- 并发测试:100 并发 gRPC → Director throughput
- 内存占用:100 万 blocks 的内存 RSS
- 验证:Report 产出性能数据,与 §性能目标 对比
- 内容:
- 在真实 vLLM + LMCache 环境中部署 Rectifiers Connector
- 验证 LMCache L2 后端可正确使用 RDMAS 存储
- 验证 Director 收到来自真实 Connector 的 report_store 上报
- 产出文件:
examples/lmcache_vllm_config.json
- 验证:vLLM 推理请求成功通过 Rectifiers 全链路
- 产出文件:
docker/Dockerfile.directordocker/Dockerfile.routerdocker/Dockerfile.orchestratordocker/docker-compose.yml(全套本地开发环境)
- 内容:
- 多阶段构建,最终镜像 < 100MB
- docker-compose 一键启动:RDMAS nodes + Director + Router + Orchestrator + mock vLLM
- 验证:
docker-compose up全部服务 healthy
- 产出文件:
README.md(项目概览 + 快速开始)docs/deployment.md(生产部署指南)docs/lmcache-integration.md(LMCache 集成步骤)docs/api.md(gRPC API 参考)
- 验证:按文档步骤可从零开始部署
- 产出文件:
.github/workflows/ci.yml
- 内容:
cargo test全部 cratecargo clippy -- -D warningscargo fmt --checkcargo build --release
- 验证:PR 触发 CI 通过
| 风险 | Phase | 检查点 | 若失败则 |
|---|---|---|---|
| RDMAS 接口漂移 | P4 | cargo build 编译不过 |
锁定旧版 git tag |
LMCache native_plugin 接口不兼容 |
P4 | PyO3 导出签名对不上 | 适配或等待上游 |
| tokenizers crate 加载模型失败 | P6 | tokenizer.json 格式/路径 | 回退到调 vLLM tokenize API |
| Director 内存膨胀 | P8 | 压测 100 万 entries 内存 > 500MB | 加 LRU 淘汰 + Bloom filter |
rectifiers/
├── Cargo.toml
├── crates/
│ ├── rdmas-director/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── lib.rs
│ │ ├── main.rs # gRPC server 入口
│ │ ├── types.rs # ModelContext, BlockEntry, NodeId
│ │ ├── context_index.rs # ContextIndex
│ │ ├── prefix_index.rs # PrefixIndex
│ │ ├── registry.rs # InstanceRegistry
│ │ ├── query.rs # Query gRPC handler + block hash 计算
│ │ ├── report.rs # ReportStore/ReportRemove gRPC handler
│ │ ├── server.rs # tonic server 启动
│ │ └── stats.rs # IndexStats
│ │
│ ├── rdmas-router/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── lib.rs
│ │ ├── main.rs # axum HTTP server 入口
│ │ ├── config.rs # RouterConfig
│ │ ├── tokenize.rs # TokenizerService
│ │ ├── director.rs # Director gRPC client
│ │ ├── decision.rs # select_best_worker()
│ │ ├── proxy.rs # HTTP dispatch to worker
│ │ └── stream.rs # SSE stream 透传
│ │
│ ├── rdmas-orchestrator/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── lib.rs
│ │ ├── main.rs
│ │ ├── config.rs # AutoTuneConfig
│ │ ├── stats.rs # StatsCollector
│ │ ├── decision.rs # AutoTuner::evaluate()
│ │ └── reconfigure.rs # VllmClient
│ │
│ └── rectifiers-connector/
│ ├── Cargo.toml # cdylib, dep: rdmas (git)
│ └── src/
│ ├── lib.rs # PyO3 entrypoint
│ ├── config.rs # RectifiersConfig
│ ├── director_client.rs # Director gRPC client
│ └── connector.rs # Wrap + report_store/remove 织入
│
├── proto/
│ ├── director.proto
│ └── orchestrator.proto
│
├── prototypes/
│ └── router-py/
│ ├── requirements.txt
│ ├── main.py
│ ├── director_client.py
│ ├── router.py
│ ├── stream.py
│ ├── test_e2e.py
│ └── VERIFICATION.md
│
├── tests/
│ ├── mock_rdmas.rs
│ ├── mock_vllm.rs
│ ├── e2e_test.rs
│ └── fault_test.rs
│
├── benches/
│ ├── director_bench.rs
│ └── router_bench.rs
│
├── docker/
│ ├── Dockerfile.director
│ ├── Dockerfile.router
│ ├── Dockerfile.orchestrator
│ └── docker-compose.yml
│
├── examples/
│ └── lmcache_vllm_config.json
│
├── .github/workflows/
│ └── ci.yml
│
└── docs/
├── architecture.md
├── development-plan.md # 本文档
├── deployment.md
├── lmcache-integration.md
└── api.md