跳到内容

多请求流式传输

单机上的多请求流式传输 (MRS)

1. 背景与范围

  • 所有处理都在单台物理机上运行,采用多进程、按阶段划分的工作进程。不涉及代理或网络传输。
  • 与 vllm-omni 的当前对齐:OmniLLM 支持多个阶段 (OmniStage)。GPU 运行器已暴露流式步骤 (预填充/解码/扩散),但入口层仍收集列表,缺乏阶段内流式传输和窗口调度。
  • 目标:在本地实现多阶段、多请求流式传输 (MRS)。每个阶段输出片段;下游阶段根据配置的窗口进行拼接和触发计算。共享内存和零拷贝策略可减少数据移动开销。

2. 关键约束

  • 每阶段多进程:每个阶段都是一个独立的进程,带有 while 循环;设备可见性可配置 (CUDA_VISIBLE_DEVICES/torch.cuda.set_device)。
  • 简单 IPC (基于复制):使用 multiprocessing.Queue/Pipe 进行进程间通信,包含 CPU 复制/序列化;此版本不依赖 CUDA IPC/SHM 零拷贝。
  • 跨阶段流水线:不同阶段可并发处理不同请求 (例如,阶段 A 处理请求 1,阶段 B 处理请求 0)。

3. 架构概览

  • 进程与 IPC 队列
  • 每个“子阶段”是一个操作系统进程 (工作进程)。循环:从 input_queue 取出 → 计算 → 放入 output_queue。
  • 通过 IPC 进行阶段间连接:基于复制的 multiprocessing.Queue 传递 dict 负载;使用共享内存处理大型对象。
  • 每个连接是 SPSC (单生产者/单消费者):上游是协调器,下游是单个阶段进程;队列在协调器侧是无界的 (maxsize=0)。
  • 设备可见性
  • 每个阶段设置 CUDA_VISIBLE_DEVICES 或调用 torch.cuda.set_device 来绑定到 GPU 集合。
  • 一个阶段内部可能使用多个 GPU (TP/PP/DP),但作为一个单一阶段单元对外呈现。
  • 简化的 IPC:使用基于复制的队列/管道进行数据传输;零拷贝是未来的工作。
  • 流水线进展:当一个阶段完成一个请求时,它会将输出入队到下游阶段;如果下游空闲,则立即启动。
  • 调度
  • 下游阶段仅在上游完成请求后触发。
  • 未实现窗口化分段/拼接触发;未提供阶段内流式传输。

4. IPC 实现 (简化:基于复制)

  • 使用 multiprocessing.Queue/Pipe 进行进程间通信 (控制 + 数据)。
  • 数据通过 CPU 进行序列化/复制;此版本不包含 CUDA IPC/SHM 零拷贝。
  • 反压:队列无界;压力表现为计算速率差异。可选的 SHM 可降低大型对象传输成本;记录 RX/解码开销以供观察。

5. 调度与取消 (简化)

  • 流水线:当一个阶段完成一个请求时,它会将其入队到下一个阶段;下一个阶段立即从其输入队列中拉取下一个请求,从而实现跨阶段并发。
  • 取消/超时:未提供显式取消/超时;优雅关闭使用发送到每个阶段输入队列的 None 哨兵。

短序列示例 (req0/req1, 阶段 A→B)

1) t0: 阶段 A 处理 req0 2) t1: req0 在 A 完成 → 进入 B;A 立即开始处理 req1 3) t2: B 处理 req0,而 A 处理 req1 (跨阶段并行)

6. 集成点 (按文件)

  • vllm_omni/entrypoints/omni.py (协调器)
  • Omni 协调多进程阶段;并行构建 OmniStage 实例并生成每个阶段的工作进程。
  • 根据配置生成阶段进程 (设置 CUDA_VISIBLE_DEVICES/torch.cuda.set_device),创建控制/数据通道,构建简单的全触发流程。
  • 统计/日志记录默认禁用;仅在显式启用时才写入每个阶段和协调器的统计信息。
  • 管理进程生命周期:启动/等待就绪,优雅关闭;使用基于复制的 IPC 和可选的 SHM 在阶段之间转发结果。
  • 阶段就绪:每个阶段初始化后发出 {"type": "stage_ready"};协调器等待所有阶段就绪或超时并记录诊断建议。