LeRobot documentation
流式视频编码指南
流式视频编码指南
1. 概述
流式视频编码消除了视频数据集录制过程中的传统 PNG 往返操作。而不是:
- 捕获帧 -> 将 PNG 写入磁盘 -> (回合结束时)读取 PNG -> 编码为 MP4 -> 删除 PNG
帧可以在捕获过程中实时编码:
- 捕获帧 -> 排队至编码器线程 -> 直接编码为 MP4
这使得 save_episode() 几乎可以即时完成(在剧集结束时视频已经编码完毕),并消除了剧集之间先前存在的阻塞等待,尤其是在长剧集中使用多个摄像头时。
2. 调整参数
| 参数 | CLI 标志 | 类型 | 默认 | 描述 |
|---|---|---|---|---|
streaming_encoding | --dataset.streaming_encoding | bool | False | 在捕获期间启用实时编码 |
vcodec | --dataset.rgb_encoder.vcodec | str | "libsvtav1" | 视频编解码器。"auto" 可自动检测最佳硬件编码器 |
encoder_threads | --dataset.encoder_threads | int \| None | None(自动) | 每个编码器实例的线程数。None 将交由 vcoded 自行决定 |
encoder_queue_maxsize | --dataset.encoder_queue_maxsize | int | 30 | 每个摄像头的最大缓冲帧数(30fps 下约 1 秒)。会占用内存 |
3. 性能考量
流式编码意味着 CPU 在捕获循环期间对视频进行编码,而不是在循环结束后进行。这会产生一个 CPU 预算,需要在以下各项之间共享:
- 控制循环(读取摄像头、控制机器人、写入非视频数据)
- 编码器线程(每个摄像头一个线程池)
- 重新运行可视化(如果已启用)
- 操作系统和其他进程
分辨率和摄像头数量的影响
| 设置 | 吞吐量(像素/秒) | CPU 编码加载 | 备注 |
|---|---|---|---|
| 2camsx 640x480x3 @30fps | 55M | 低 | 适用于大多数系统 |
| 2camsx 1280x720x3 @30fps | 165M | 中等 | 在现代系统上运行流畅 |
| 2camsx 1920x1080x3 @30fps | 373M | 高 | 需要强大的高端 CPU |
encoder_threads 调优
此参数控制每个编码器实例内部使用的线程数:
- 较高的值(例如 4-5):编码速度更快,但每个摄像头占用的 CPU 核心数更多。适用于拥有大量核心的高端系统。
- 较低的值(例如 1-2):每个摄像头占用的 CPU 更少,从而为核心释放资源用于捕获和可视化。适用于低分辨率图像和性能较强的 CPU。
None(默认值):由编解码器自行决定。相关信息可在编解码器日志中查看。
背压与帧丢弃
每个相机都有一个有界队列(encoder_queue_maxsize,默认 30 帧)。当编码器无法跟上时:
- 队列填满(消耗 RAM)
- 新帧会被丢弃(而非阻塞)——捕获循环持续不间断地运行
- 会记录一条警告:
"Encoder queue full for {camera}, dropped N frame(s)" - 在回合结束时,会报告每个相机的总丢帧数
编码器落后的症状
- 系统感觉卡顿并冻结:所有 CPU 均达到 100%
- 日志中出现的 丢帧警告,或录制数据集中帧数/FPS 低于预期
- 机器人动作卡顿:如果 CPU 严重过载,即使是捕获循环也可能受到影响
- 累积重跑延迟:可视化落后于实时
4. 硬件加速编码
何时使用
在以下情况下使用硬件编码:
- CPU 是瓶颈(出现丢帧、机器人动作卡顿、rerun 延迟)
- 您拥有兼容的硬件(GPU 或专用编码器)
- 您正在以高吞吐量进行录制(高分辨率或使用多个摄像头)
选择编解码器
| 编解码器 | CPU 使用率 | 文件大小 | 质量 | 备注 |
|---|---|---|---|---|
libsvtav1(默认) | 高 | 最小 | 最佳 | 默认。压缩效果最佳,但 CPU 负载最高 |
h264 | 中等 | ~30-50% 更大 | 好的 | 软件 H.264。更低的 CPU |
| 硬件编码器 | 非常低 | 最大 | 好的 | 卸载到专用硬件。最适合 CPU 受限的系统 |
可用的硬件编码器
| 编码器 | 平台 | 硬件 | CLI 值 |
|---|---|---|---|
h264_videotoolbox | macOS | Apple Silicon / Intel | --dataset.rgb_encoder.vcodec=h264_videotoolbox |
hevc_videotoolbox | macOS | Apple Silicon / Intel | --dataset.rgb_encoder.vcodec=hevc_videotoolbox |
h264_nvenc | Linux/Windows | NVIDIA GPU | --dataset.rgb_encoder.vcodec=h264_nvenc |
hevc_nvenc | Linux/Windows | NVIDIA GPU | --dataset.rgb_encoder.vcodec=hevc_nvenc |
h264_vaapi | Linux | Intel/AMD 显卡 | --dataset.rgb_encoder.vcodec=h264_vaapi |
h264_qsv | Linux/Windows | Intel Quick Sync | --dataset.rgb_encoder.vcodec=h264_qsv |
auto | 任意 | 探测系统中可用的硬件编码器。如果未找到硬件编码器,则回退到 libsvtav1 | --dataset.rgb_encoder.vcodec=auto |
要使用硬件加速编码器,您可能需要升级 GPU 驱动程序。
libsvtav1是默认选项,因为它能提供最佳的训练性能;其他 vcodecs 可以降低 CPU 占用并提升速度,但通常会产生更大的文件,并可能影响训练时间。
5. 故障排除
| 症状 | 可能的原因 | 修复 |
|---|---|---|
| 系统冻结或机器人动作卡顿或 Rerun 可视化延迟 | CPU 资源不足(负载使用率 100%) | 关闭其他应用程序,降低编码吞吐量,调低 encoder_threads,使用 h264,使用 display_data=False。如果 CPU 仍然持续处于 100% 状态,则可能无法满足您的配置需求,请考虑使用 --dataset.streaming_encoding=false 或硬件编码(--dataset.rgb_encoder.vcodec=auto) |
| 数据集中出现“Encoder queue full”警告或丢帧 | 编码器跟不上(队列溢出) | 如果 CPU 未达到 100%:请增加 encoder_threads,增加 encoder_queue_maxsize,或使用硬件编码(--dataset.rgb_encoder.vcodec=auto)。 |
| 高内存使用 | 队列填充速度超过编码速度 | encoder_threads 设置过低或 CPU 资源不足。请降低 encoder_queue_maxsize 或改用硬件编码 |
| 大型视频文件 | 使用硬件编码器或 H.264 | 预期的权衡。如果 CPU 允许,请切换到 libsvtav1 |
save_episode() 仍然很慢 | streaming_encoding 为 False | 设置 --dataset.streaming_encoding=true |
| 编码器线程崩溃 | 编解码器不可用或设置无效 | 检查 vcodec 是否已安装,尝试使用 --dataset.rgb_encoder.vcodec=auto |
| 记录的 dataset 缺少 frames | CPU/GPU 资源耗尽或偶发的负载峰值 | 如果约 5% 的帧丢失,您的系统很可能已过载——请遵循上述建议。如果丢失的帧较少(约 2%),它们可能是由偶尔的瞬时负载峰值(通常在启动时)引起的,可以视为预期行为。 |
6. 推荐配置
这些估算较为保守;我们建议您在自己的环境中进行测试——从低负载开始,逐步增加负载。
高端系统:现代 12 核及以上(24 线程及以上)
在 CPU 上,约 250-500M px/sec 的吞吐量应该比较舒适。如果可用,尝试使用硬件编码以获得更好的效果。
# 3camsx 1280x720x3 @30fps: Defaults work well. Optionally increase encoder parallelism.
# 2camsx 1920x1080x3 @30fps: Defaults work well. Optionally increase encoder parallelism.
lerobot-record --dataset.encoder_threads=5 ...
# 3camsx 1920x1080x3 @30fps: Might require some tuning.中端系统:现代 8 核及以上(16 线程及以上)或 Apple Silicon
在 CPU 上,吞吐量应可达到约 80-300M px/sec。
# 3camsx 640x480x3 @30fps: Defaults work well. Optionally decrease encoder parallelism.
# 2camsx 1280x720x3 @30fps: Defaults work well. Optionally decrease encoder parallelism.
lerobot-record --dataset.encoder_threads=2 ...
# 2camsx 1920x1080x3 @30fps: Might require some tuning.低资源系统:现代 4 核及以上(8 线程及以上)或 Raspberry Pi 5
在资源非常受限的系统上,流式编码可能会与捕获循环产生过重的竞争。禁用该功能会回退到基于 PNG 的方案,其中编码发生在回合之间(会阻塞,但不会干扰捕获)。或者,以较低的吞吐量进行录制,以降低捕获和编码的负载。还可以考虑将编解码器更改为 h264 并使用批量编码。
# 2camsx 640x480x3 @30fps: Requires some tuning.
# Use H.264, disable streaming, consider batching encoding
lerobot-record --dataset.rgb_encoder.vcodec=h264 --dataset.streaming_encoding=false ...7. 结语
性能最终取决于您的具体配置——每秒帧数、分辨率、CPU 核心数及负载、可用内存、回合长度以及您选择的编码器。请务必针对目标工作负载进行测试,注意您的 CPU 及系统能力,并合理调整 encoder_threads、encoder_queue_maxsize 和 vcodec。话虽如此,一种常见的实用配置(适用于许多应用)是三台相机以 640×480x3 @30fps 运行;在现代系统中,这通常可以配合默认的流式视频编码设置正常运行。请始终通过将视频时长与 CLI 回合时长进行比较,并确认行数等于 FPS × CLI 时长,来验证您记录的 dataset 是否健康。