DeepInfer 部署前先核对显存与并行切分,再跑一次最小推理请求

文章导读
DeepInfer 起不来,多数不是“装错了”,而是装之前没把两个数字对齐:每张卡实际能留给模型的显存,以及并行切分数和真实卡数是否一致。建议的顺序是先查设备把卡数和单卡显存固定成一行结论,再按权重占用加缓存占用估出每卡预算,把切分数写成不超过卡数的值,最后发一次最小推理请求确认服务能返回结果,而不是只看进程有没有起来。这条路径适用于单机多卡的自建部署;如果卡被其他进程占用、驱动版本混杂或模型权重
📋 目录
  1. 一 用设备查询命令确认卡数、单卡显存与驱动状态
  2. 二 按权重占用与缓存占用估出每卡预算
  3. 三 把并行切分数与实际卡数对齐,写出最小启动配置
  4. 四 发一次最小推理请求确认端到端可用
  5. 五 启动失败时按顺序读三类日志
A A

DeepInfer 起不来,多数不是“装错了”,而是装之前没把两个数字对齐:每张卡实际能留给模型的显存,以及并行切分数和真实卡数是否一致。建议的顺序是先查设备把卡数和单卡显存固定成一行结论,再按权重占用加缓存占用估出每卡预算,把切分数写成不超过卡数的值,最后发一次最小推理请求确认服务能返回结果,而不是只看进程有没有起来。这条路径适用于单机多卡的自建部署;如果卡被其他进程占用、驱动版本混杂或模型权重量级超出单卡,需要先解决这些前置条件再谈参数。

判断方向:部署前先做三件事——用设备查询命令确认卡数与单卡显存,按“权重占用除以切分数加缓存余量”估每卡预算,把并行切分数限制在实际卡数以内。配置写完后不要只看启动日志是否报错,要发一次最小推理请求,从返回结构、首字延迟和总耗时三处确认端到端可用。显存占比、最大并发这类参数没有通用最优值,需要结合本机卡数和模型规模现场调,估算数字只能当起点,不能当结论。

用设备查询命令确认卡数、单卡显存与驱动状态

估显存最怕的前提错误是“以为有 4 张卡,其实只有 2 张可见”。先跑设备查询,再谈配置。NVIDIA 环境常用下面这条,输出简洁、字段好读:

nvidia-smi `--query-gpu`=index,name,memory.total,memory.used,driver_version `--format`=csv

要读的字段只有四个:index 是卡序号,决定并行切分数最多能写多大;memory.total 是单卡总显存;memory.used 是当前已占用,非零说明有别的进程在跑,估出来的预算要相应打折;driver_version 用来确认多卡之间驱动是否一致。如果容器内看不到卡,还要在容器里再跑一次同样的命令,确认是宿主有卡而容器没透传,而不是真的没卡。

查完后把结果压成一行结论,写在部署记录或配置文件旁边,例如“可见 2 张卡,单卡总显存约 24GB,当前占用接近 0,驱动版本一致”。后面所有估算和切分都以这一行为准,避免中途换机器或换容器后还按旧卡数配参数。

按权重占用与缓存占用估出每卡预算

可写进配置的单卡预算,通常按这个思路估:单卡预算 ≈ 模型权重总占用 ÷ 并行切分数 + 运行时缓存余量。权重占用可以按参数量乘以每参数字节数粗算,半精度大约每参数 2 字节,量化后更小;缓存余量包括激活值、KV 缓存和框架自身的开销,这部分随最大并发和输入长度变化,建议先留出较宽的余量,跑通后再逐步收紧。

DeepInfer 部署前先核对显存与并行切分,再跑一次最小推理请求

两组输入示例(均为估算,用于演示算法,不是官方数据):

  • 模型约 70 亿参数、半精度权重、2 卡切分:权重约 14GB 量级,切分后每卡约 7GB 量级,加缓存余量后单卡预算可以按十几 GB 量级先配。
  • 模型约 700 亿参数、半精度权重、4 卡切分:权重约 140GB 量级,切分后每卡约 35GB 量级,这个量级已经接近或超过常见单卡容量,需要先确认卡型,或者改用量化权重、增加卡数。

估算值的作用是决定“先按哪个量级配”,不是替代实测。第一轮配置后如果启动即显存不足退出,优先调大三件事之一:增加切分数(不超过卡数)、降低最大并发、改用量化权重,而不是反复重启碰运气。

把并行切分数与实际卡数对齐,写出最小启动配置

并行切分数大于可见卡数,是初始化阶段最常见的失败原因之一,表现往往是进程刚起就退出,日志里出现设备数不匹配或通信初始化失败。最小启动配置骨架如下,字段名按你所用版本的配置格式替换,含义保持一致:

tensor_parallel_size: 2      # 并行切分数,必须小于等于可见卡数
gpu_memory_utilization: 0.85 # 单卡显存占比,剩余部分留给缓存与框架开销
max_concurrent_requests: 4   # 最大并发,直接影响 KV 缓存占用与单卡预算

三项各自的含义要分清:并行切分数决定权重怎么摊到多卡,写超过卡数一定失败;显存占比是框架允许自己使用的显存上限,配得太接近 1 会把缓存挤掉,配得太低则权重放不下;最大并发决定同时在跑的请求数,是缓存占用的主要来源,第一轮建议从小值起步。三项之间是联动关系,改一个就要回头看另外两个还成不成立。

DeepInfer 部署前先核对显存与并行切分,再跑一次最小推理请求

发一次最小推理请求确认端到端可用

进程起来只说明加载完成,不说明服务能出结果。用一个短输入、短输出的请求打一次,命令按实际端口和路径替换:

curl -s http://127.0.0.1:8000/v1/completions \
  -H 'Content-Type: application/json' \
  -d '{"prompt":"你好","max_tokens":16}'

预期返回是一个 JSON 对象,至少包含生成的文本字段、结束原因字段和用量统计字段(输入与输出 token 数)。判断点有三个:返回体是合法 JSON 而不是错误页或空体;生成文本字段非空;结束原因符合预期,比如达到长度上限或正常结束。如果返回体里带错误字段,按字段里的类型去对应下一节的日志排查,不要先改配置。

首字延迟和总耗时放在同一轮观察:首字延迟反映排队和预填充开销,总耗时反映解码速度,两者差距过大通常指向最大并发配得过高或缓存余量不足。记录这一次的数值作为基线,后面调参时用同一条命令对比。

启动失败时按顺序读三类日志

不要从头翻整个日志,按“显存 → 切分 → 端口”的顺序定位,大多数失败能在前两类里区分开。

  • 显存不足:日志里通常出现显存分配失败、超出容量的提示。判断依据是启动后很快退出且伴随分配错误;下一步动作是降低显存占比之外的最大并发、增加切分数或改用量化权重,再重启一次。
  • 切分不匹配:日志里通常出现设备数量或通信初始化相关的报错。判断依据是并行切分数大于可见卡数,或容器内可见卡数与宿主不一致;下一步动作是回到第一步的设备查询命令重新确认卡数,再把切分数改成不超过卡数。
  • 端口占用:日志里通常出现地址已被使用、绑定失败的提示。判断依据是进程没到加载模型阶段就退出;下一步动作是换端口或找到占用该端口的进程后释放,再重发最小推理请求验证。

三类日志的排查顺序不要打乱:显存和切分问题会在加载阶段暴露,端口问题更早,如果先处理端口却忽略了显存估算偏差,会出现“端口通了但还是起不来”的反复。每改一处配置,都用同一条设备查询命令、同一条最小推理请求做一次前后对照,把每次结果记下来,比凭印象判断可靠。