多 GPU、通道与推理后端¶
通道¶
通道是一组 GPU,拥有自己的推理进程、调度器和预约日历。首次启动时 SlotServe 会创建一个包含 nvidia-smi 检测到的全部 GPU 的通道,所以单卡机器无需任何设置,界面上也不会出现通道相关的内容。
有多张卡时,在管理 → GPU 与通道中自行划分:
| 划分方式 | 通道 | 适合 |
|---|---|---|
| 一张大卡 | GPU 0,1,2,3 |
需要全部显存的大模型(张量并行) |
| 每卡一个通道 | GPU 0、GPU 1… |
多人同时使用 |
| 混合 | GPU 0+1、GPU 2、GPU 3 |
一个大模型加若干小模型 |
规则:
- 一张 GPU 最多属于一个通道。修改通道的 GPU 会重启该通道的进程。
- 每个通道有自己的默认模型,通道空闲时供所有人使用。通道空闲时也可以改为运行共享开发环境或什么都不运行。
- 启动参数用于修改通道当前模型的参数,保存后所有运行该模型的通道会重新加载;重新加载会重启该通道的推理进程。参数属于模型,在所有通道上都生效。
- 预约、候补、手动加载/卸载、加载失败回退都按通道独立进行;配额按人跨通道累计。
- 还有未结束预约的通道不能删除,最后一个通道也不能删除。
- 每个通道的进程设置
CUDA_VISIBLE_DEVICES为其 GPU,监听端口为SLOTSERVE_LLAMA_PORT + 通道号 - 1,日志分开保存(llama-server-lane<N>.log)。
接口请求由哪个通道处理¶
flowchart TD
req(["带有效密钥的请求"]) --> named{"指定了模型名?"}
named -- "是" --> usable{"你可用的通道在提供它?<br/>先看自己预约的,再看空闲的"}
usable -- "是" --> that["发往该通道"]
usable -- "否" --> taken{"别人预约的通道<br/>在提供它?"}
taken -- "是" --> r403["403 gpu_reserved"]
taken -- "否" --> known{"是已登记的模型?"}
known -- "是" --> r409["409 model_not_loaded"]
known -- "否,不认识的名字" --> mine
named -- "否" --> mine{"你有进行中的预约?"}
mine -- "是" --> own["你的通道"]
mine -- "否" --> ready{"有模型已就绪的<br/>空闲通道?"}
ready -- "是" --> first["第一个这样的通道"]
ready -- "否" --> anyfree{"有空闲通道?"}
anyfree -- "是" --> wait["第一个空闲通道<br/>就绪前返回 503 + Retry-After"]
anyfree -- "否" --> r403b["403 gpu_reserved"]
文字说明:
- 请求指定了模型名:发往调用者可用(空闲或自己预约)且正在提供该模型的通道,优先自己预约的通道。只有别人预约的通道提供该模型时返回
403 gpu_reserved;已登记但所有可用通道都没加载时返回409 model_not_loaded。 - 未指定模型名:有自己的预约就用自己的通道,否则用第一个模型已就绪的空闲通道。
/v1/models列出调用者当前能用的所有模型。
推理后端¶
每个模型选择一个推理后端,调度、预约和网关对所有后端完全一样。
| 后端 | 模型来源 | SlotServe 执行的命令 | 就绪判断 |
|---|---|---|---|
| llama.cpp(默认) | .gguf 文件 |
llama-server -m <文件> --host --port --alias <名称> <参数> |
/health 返回 200 |
| vLLM | 仓库名或目录 | vllm serve <模型> --host --port --served-model-name <名称> <参数> |
/health 返回 200 |
| SGLang | 仓库名或目录 | python -m sglang.launch_server --model-path <模型> --host --port --served-model-name <名称> <参数> |
/health 返回 200 |
| 自定义 | 任意 | 你的命令模板,如 my-server --model {model} --port {port} |
配置的健康检查路径返回 200 |
- 在模型 → 添加模型中添加。扫描和下载得到的
.gguf文件自动登记为 llama.cpp 模型。 - 各后端的启动命令是管理员设置(管理 → 系统设置 → 推理后端),命令需要在 SlotServe 运行的环境里可用。
- SlotServe 自己设置的参数(地址、端口、模型、服务名称)会从你的参数中去掉。多卡通道做张量并行时,请自行加上如
--tensor-parallel-size 2(vLLM)或--tp 2(SGLang)。 - 网关总会把服务名称发给后端,所以客户端可以不填
model。
谁可以设置哪些参数¶
模型服务以 SlotServe 自身的权限运行,因此部分参数等同于在服务器上执行代码或写文件(--trust-remote-code、插件和模块类参数、以 -file、-path、-dir 结尾的参数、--log*、--ssl*、--api-key 等)。
- 成员可以使用各后端的调优参数(上下文长度、GPU 层数、并行、批大小、缓存类型、采样默认值等),模型路径只能指向模型目录、模型库或 Hugging Face 仓库 ID。
--mmproj这类文件参数必须指向模型目录或模型库中的文件。 - 其他参数会被拒绝;成员也可以选择提交申请:批准前模型保持当前参数,管理员会收到通知并在模型页批准或拒绝。预设不支持申请,请让管理员设置。
- 管理员可以设置任何参数,但上面列出的参数需要先明确确认。每次修改都会写入审计日志(
model.args_update)。 - 自定义后端仅限管理员。模型目录一键部署只会生成允许的参数。
在 Docker 中使用 vLLM¶
默认镜像只包含 Python 和 SlotServe,llama.cpp 从宿主机挂载。要用 vLLM,请构建基于 vLLM 官方镜像的版本:
docker build -f Dockerfile.vllm -t slotserve-vllm .
echo "SLOTSERVE_IMAGE=slotserve-vllm" >> .env
docker compose up -d
请把构建参数 VLLM_IMAGE 固定到支持你的 GPU 和驱动的 vLLM 版本。llama.cpp 仍可照常挂载,两种后端可同时使用。
审批模式¶
管理 → 系统设置 → 账号 → 审批决定预约是否需要管理员审批:
| 模式 | 需要审批的预约 |
|---|---|
| 关闭(默认) | 无 |
| 长预约 | 超过「超过多久需审批」(默认 4 小时)的预约 |
| 全部预约 | 所有预约 |
管理员自己的预约、管理员替他人建的预约都不需要审批。待审批的预约会占住时段(别人不能再约)并计入配额,但不会为它加载模型。管理员在管理 → 预约 → 待审批中,或通过聊天消息里的按钮(Telegram、飞书 / Lark)或编号选项(钉钉、企业微信、QQ)通过或拒绝;每周重复的系列可以一次处理。到开始时间仍未审批的申请会自动失效,时段释放给候补的人。
stateDiagram-v2
direction LR
state "待审批" as pending
state "已预约" as booked
state "已拒绝" as rejected
state "已过期" as expired
state "已取消" as cancelled
[*] --> pending: 需要审批
[*] --> booked: 无需审批
pending --> booked: 通过
pending --> rejected: 拒绝
pending --> expired: 到开始时间仍未审批
pending --> cancelled: 撤回
booked --> cancelled: 开始前取消
booked --> [*]: 时段结束或提前结束