问题:配置不对劲
最近在 CNB(腾讯云)上调 GPU 并发时配过一次 CI_VIDEO_CONCURRENT=3、CI_BATCH_SIZE=32。但 CPU 环境的配置一直是很久以前从一个小内存机器上搬过来的——没改过。
直到有天心血来潮看了一眼 CPU workspace 的 .cnb.yml:
env:
CI_DEVICE: cpu
CI_BATCH_SIZE: "4"
CI_VIDEO_CONCURRENT: "1"
一个 CPU 8 核的机器,concurrent=1,正在串行处理视频。

再一查文档——CNB 默认 CPU Dev Workspace 是 8 核 16GB。等于手里拿了 8 条车道但只开了 1 条。
对比:GPU 配置是好的坐标系
同样工程,GPU 环境的配置完全不一样:
| 参数 | GPU | CPU(改前) | CPU(改后目标) |
|---|---|---|---|
CI_VIDEO_CONCURRENT |
3 | 1 | 2 |
CI_BATCH_SIZE |
32 | 4 | 8 |
cpus (runner) |
8 | 未指定 | 8 |
GPU 并发数是 CPU 的 3 倍,batch 是 8 倍。说明 CPU 配置不是”本来就该这么小”,而是从旧环境迁移时没调。
为什么 CPU 也能并行
这个 CI 脚本的核心逻辑是:每个视频独立下载→处理→上传。各个视频之间没有共享状态,天然适合并行。
max_concurrent = int(os.environ.get("CI_VIDEO_CONCURRENT", "1"))
batch_size = os.environ.get("CI_BATCH_SIZE", "4" if device == "cpu" else "8")
with ThreadPoolExecutor(max_workers=max_concurrent, ...) as executor:
for video in pending_videos:
executor.submit(process_single_video, video, batch_size)
关键判断:
- 并发(
concurrent):开几个线程并行处理视频。每个线程独立跑一个 YOLO 推理 subprocess,各占约 4 核。2 个并发正好用满 8 核 - 批次(
batch):单视频内攒多少帧再做一次批量推理。batch 越大,单位帧的推理成本越低 - CPU 核数(
cpus):不显式声明的话,CNB 调度器可能给更少的核

所以最终只改了三个参数:
# 改前
CI_BATCH_SIZE: "4"
CI_VIDEO_CONCURRENT: "1"
# runner: 无 cpus
# 改后
CI_BATCH_SIZE: "8"
CI_VIDEO_CONCURRENT: "2"
runner:
tags: cnb:arch:amd64
cpus: 8
提交时写了这么一行:
git commit -m "opt(cpu): concurrent 1→2, batch 4→8 (8 core utilization)"
踩坑记录
1. 双 Remote 推错仓库
本地仓库配了 2 个 remote:
origin→ cnb-workspace-test(目标仓库)new-origin→ cnb-video-pipeline(历史遗留)
git push origin dev-cpu 推对了仓库,但本地分支没关联上游,git branch -vv 不显示追踪关系。差点推错。
解决方法:git ls-remote 验证 SHA 一致性,然后 git remote remove new-origin 清理多余 remote。
git ls-remote origin dev-cpu # → 939e69e(新 commit ✓)
git ls-remote new-origin dev-cpu # → d024579(旧 commit,没推到这里 ✓)
2. 本地 master 落后远程几个月
另一个工程 cnb-video-pipeline 的远程 master 已经统一架构了(用 api_trigger_cpu/cpu-processor 标签区分环境而非分支),但本地 master 还是初始提交。查文件时 git show master:.cnb.yml 直接报错。
解决方法:先 git fetch origin master,再用 git ls-tree --name-only origin/master 确认远程文件,然后 git checkout master && git pull origin master 同步。
先在 git fetch 之后再下结论——这是一个反复被纠正的经验,但确实容易忘。
3. 两处 CPU 配置需要同步
cnb-video-pipeline 工程的 .cnb.yml 中有两处涉及 CPU 配置:
api_trigger_cpu(CI 构建触发入口)cpu-processor(Workspace 开发环境)
两处都是 CPU 环境,改了第一个忘了第二个就麻烦了。改完后 grep 确认全覆盖。
4. 推送被远程拒绝
git push origin dev-cpu 报 ! [rejected] dev-cpu → dev-cpu (fetch first)。远程有本地没有的提交——之前在别处直接改了远程。
解决:git pull origin dev-cpu --rebase 变基后重新推送。
最终结果
两个工程的并行配置都从 1 串行调到了 2 并行:
| 工程 | 改前 concurrent |
改后 | 改前 batch |
改后 | cpus |
|---|---|---|---|---|---|
| cnb-test | 1 | 2 | 4 | 8 | 未设→8 |
| cnb-video-pipeline | 1 | 2 | 4 | 8 | 2→8 |
同时把 cnb-video-pipeline 从 3 分支(dev-cpu, dev-gpu, master)整理为单 master 分支——远程 master 已统一架构,不再需要独立分支。
可复用的经验
- CI 平台的 CPU 资源往往比预期的多。 文档上写着 8 核,但默认配置保守,不等于真正拿到了 8 核。
cpus一定要显式声明。 CNB 不设cpus可能会走调度器的默认值,而不是真正的 8 核。- batch 和 concurrent 是两回事。 一个控制单视频内部的帧批量,一个控制多视频之间的并行度,需要独立调优。
- GPU 配置是好的参考坐标系。 如果你有 GPU 环境的参数,可以反推 CPU 的合理范围——GPU 对并行度的要求更高,CPU 按比例降低就能得到一个安全的初始值。
- 远程验证用
git ls-remote。git push的输出可能让人误以为推成功了,git ls-remote返回 SHA 签名——确认才是硬道理。
总结
这次调优本质上只干了三件事:把 concurrent 从 1 改成 2,batch 从 4 改成 8,加上 cpus: 8。没有改代码逻辑,没有引入新框架,纯配置改动。
有时候优化就是”发现已经有的资源,让代码真正用上它”。