尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

神经视频编码:从手写规则到自寻最优的端到端压缩

发布时间:2026/9/29 18:15:18

资讯中心
01
ARTICLE

神经视频编码:从手写规则到自寻最优的端到端压缩

神经视频编码:从手写规则到自寻最优的端到端压缩
写这篇分享的起因是某天在Windows工作机上跑数据预处理终端里刷出来一行UnicodeEncodeError: gbk codec cant encode character \ue687 in position。这类报错对经常处理视频文件名的工程师来说并不神秘但让我有感而发的是“编码”这个词在视频领域早已换了含义。传统Codec像一本写满规则的说明书而神经视频编码正在让Codec开始“学习”把像素压成比特流的过程不再只靠人工设计的变换、预测、量化模块而是靠神经网络在率失真目标下自己摸索最优策略。这篇文章想聊清楚背后的技术逻辑也把我在训练和部署过程中踩过的工程边界问题一并列出来适合刚接触端到端压缩的工程师以及想评估是否替换H.26x方案的产品负责人。1. 从“手写规则”到“自寻最优”神经视频编码的思路转变1.1 传统Codec为什么卡在“堆规则”这道坎上视频压缩的历史本质上是在跟信息冗余作斗争。从H.264一路走到H.266/VVCCodec内部积累了一整套复杂的模块组合把画面切成16x16或者64x64的块用帧内预测和帧间运动估计去掉时间、空间冗余然后对残差做DCT变换、量化最后交给CABAC熵编码器。每一步都有非常具体的标准条款编码器和解码器必须严格遵循同一套规则才能保证“我写的码流你能解”。这种“手写规则”的模式在过去二十年里非常成功。但它的问题也很明显每个新标准都在往旧框架上增加新工具。VVC为了比HEVC再省30%到40%码率加入了仿射运动补偿、L型预测、多重变换选择等等编码复杂度直接翻了几倍。换句话说压缩效率的提升越来越依赖“专家加班加点设计规则”而每一项规则的收益都是递减的。真正逼近率失真理论上限需要的是一种能脱离固定算法逻辑、从数据中自动总结规律的手段。1.2 端到端框架一个可以梯度更新的压缩系统神经视频编码用的是另一套思路。我们把一帧图像x输入编码器网络f_s得到隐变量y对y量化成y_hat再经过熵编码器写成比特流。解码端用另一个网络g_s把y_hat恢复成重建帧x_hat。整个链路除了量化环节几乎所有模块都是可微的因此可以把它定义成一个优化问题。训练目标通常写成拉格朗日形式L R λD。R是码率估计也就是熵编码器实际消耗的比特数D是重建失真比如MSE或者MS-SSIMλ是平衡系数。λ大模型会优先保画质输出高码率λ小模型会更激进地压缩画质下降但省码率。这个式子把传统Codec里“选Qp、调码控”的复杂策略浓缩成了一个连续可调的系数剩下的交给梯度下降去求解。传统Codec和神经Codec的区别见下面这张表维度传统CodecH.265/AV1神经Codec端到端技术基础人工设计的分块、预测、变换、量化神经网络自动学习非线性变换编码模式有明确模式的块级HEVC/VVC语法隐变量张量无“块”概念熵编码模型CABAC基于固定上下文模板超先验自回归预测概率分布优化方式率失真优化大量分支决策梯度下降端到端联合优化硬件友好度已有大量硬编解码器芯片GPU/TPU依赖度高移动端困难增益来源更细的块划分和模式更精准的隐变量概率估计端到端框架最大的价值是让“编码”和“解码”不再是两个独立模块而是一个可以协同优化的系统。编码器网络知道解码器网络的统计特性可以主动把能量集中到人眼更敏感的频带上。传统Codec里面“变换基是固定的DCT”这个约束被神经网络直接打破了。1.3 率失真曲线如何理解λ和码率的关系实际项目中很少只训练一个模型就算完。我们会把λ按指数间隔取一组值比如0.001、0.003、0.01、0.03、0.1训练出同一网络结构下的多个checkpoint。用这些模型在标准测试序列上测PSNR/MS-SSIM就能画出一条以码率为横轴、画质为纵轴的率失真曲线。模型越好曲线越靠左上方说明“同样的码率下画质更好”。这里有个容易踩的坑不同λ的模型绝不能互相比较码率高低否则会得出“λ小画质更好”这种错误结论。论文里经常用BD-Rate来消除这个偏差它统计的是两套模型在同等级画质水平下的平均码率差异。比如“相比HEVC省了26%的BD-Rate”意思是跑到同等的PSNR时神经Codec平均少用了26%比特。我在复现别人工作的时候习惯把测试序列的每一帧都单独记录码率和PSNR再统一算BD-Rate只用几条流的平均值很容易被个别序列带偏。2. 神经Codec的三大核心模块拆解2.1 超先验让熵模型获得“看图说话”的能力很多人最开始看神经Codec的网络结构会看到一个主编码器加一个主解码器以为这就是全部。真正让压缩率跑起来的关键其实是藏在旁边的一条辅助信息通路——超先验。早期端到端模型把隐变量当作独立同分布变量来编码完全忽视了图像的结构性平坦区域和纹理区域的统计特性完全不同用一个固定分布去描述所有位置信息熵肯定偏大。超先验做的事情是用另一个网络从y中提取出z量化后写进码流。解码端拿到z_hat通过一个小网络预测出每个隐变量通道的均值与方差这样熵编码器就能用“图像相关的条件概率”去编码y_hat。你可以把它理解成主码流在传画面细节旁路码流在传“每个位置的可压缩性预期”。两者配合算术编码器才可以更接近香农极限。参数上超先验网络本身的开销并不大通常只有主自动编码器的四分之一左右却能让码率下降20%到30%。所以现在几乎没有一个学术界模型敢不用超先验。工程实现时要注意旁路码流的码率也必须计入总码率否则就会出现“压缩率虚高”的假象。2.2 自回归上下文压缩率提升的代价是什么有了超先验模型对隐变量整体的分布有了全局感知但没有抓到局部依赖关系。图像里相邻位置的隐变量通常高度相关于是研究者把NLP领域的自回归思想搬了进来解码隐变量时按照从左到右、从上到下的顺序每生成一个元素都参考已经重建出来的邻居值。实现上最常用的是masked卷积。把当前待解区域附近的已解码值作为输入输出当前通道的条件概率参数。这种做法的确能把概率估得更准码率又降了一截但代价是串行化。隐变量不是一整张图直接解码完而是一块一块、一个通道一个通道来解码延迟成倍增加。我在实机测试时一个带三阶自回归的模型解码1080p视频单帧耗时大约是纯超先验模型的两到三倍。工程上的妥协方案也不复杂。可以把隐变量分组比如每4个通道一组组间并行、组内串行或者只在最后几个关键层保留自回归其他层仍然全并行。取舍逻辑永远是先看应用允许的最大解码时延再决定自回归的强度而不是一味追SOTA。2.3 量化难点怎么让“不可导”变成“可导”量化是神经Codec和普通图像识别最大的分水岭。推理时我们需要把浮点隐变量转成整数这个过程不连续、不可导梯度根本过不去。研究者常用的一个技巧叫STE也就是前向传播时老老实实取整反向传播时用一个恒等函数逼近量化器的梯度让误差信息能“绕过去”。另一个常见的训练技巧是给隐变量加均匀噪声。在训练前半段用连续噪声模拟量化误差避免模型对硬量化过于敏感训练后期再逐步切换成真正的取整操作。这里的细节很微妙噪声范围太大模型学到的分布和实际量化分布差得远噪声范围太小训练又不稳定。我通常的做法是保持区间长度为1但要配合学习率预热否则损失曲线会在切换点出现很明显的跳变。如果你在部署时发现“训练指标很好推理效果崩了”八成就是训练和推理之间量化模拟方式不一致。这个gap最高可以到10%以上所以在评估模型时一定要单独跑一遍推理模式的率失真数据不要只看训练loss。3. 工程落地的真实成本算力、数据与那些不起眼的错误3.1 训练一个神经Codec到底要准备什么训练神经Codec数据量并不需要像大语言模型那样夸张但质量要求很高。常用的开源数据集有Vimeo-90K、CLIC、REDS里面是短视频片段和高清大片子。我试过直接用公开数据增量训练和在一个特定领域的监控视频上重新finetune后者的码率节省会比前者多出不少。原因是监控场景的运动模式集中在平移和尺度变化模型能更容易学到规律。损失函数不能只靠PSNR。如果只用MSE训练出来的模型会把大量比特花在纹理上人眼看着反而不干净。我习惯用混合失真D (1-α)·MSE α·(1-MS-SSIM)α先从0.5开始再根据主观测试微调。同时码率项的估计也分虚实训练时用概率分布的熵近似真实码率推理时再用算术编码器实际编码。两者之间通常有微小的差异但方向一致不影响选型。训练本身很烧卡。一个中等规模的超先验上下文模型在单卡V100上跑100个epoch可能需要两三天如果输入是1080p视频块内存占用还会更大。我的建议是先用64x64或128x128的patch跑通全流程再逐步放大不要一开始就喂全高清帧。3.2 部署时速度与内存的取舍神经Codec的学术成绩漂亮但工程落地最难啃的骨头是时延。编码端不仅要跑卷积网络还要跑超先验提取、自回归上下文运算解码端则需要按顺序恢复隐变量。我实测过不少开源模型在无自回归情况下1080p单帧解码大概要几十毫秒一旦加上自回归直接飙升到两三百毫秒。这个速度在离线转码场景可以接受在视频通话场景就是灾难。内存又是另一个问题。一个大体的全精度模型参数规模在50MB左右。如果模型权重随码流分发那码率节省的部分可能被模型下发成本吃回去。有一些工作把超先验提取都推给编码端让解码端只维护固定权重这能缓解一部分压力但同时也限制了码流在不同解码设备间的兼容性。所以我在项目里一般先把模型量化到int8再放到TensorRT或ONNX Runtime里跑。int8之后解码速度能有一倍提升但率失真损失也要实测一般会退化3%~5%。做边缘端部署的话还可以考虑剪枝掉自回归分支只保留超先验把模型降到几MB速度换得过来。3.3 一个经常被忽略的工程坑文件路径和字符编码这个坑和模型算法完全无关但只要你做大规模数据管线早晚会遇到。我最开始用Python脚本遍历训练目录时在Windows环境下一旦碰到文件名里带特殊字符终端输出阶段就会报出UnicodeEncodeError: gbk codec cant encode character \ue687 in position。原因是Windows命令行默认用GBK编码输出而Python在做print或日志重定向时如果没有手动指定编码就会尝试用当前区域设置去编码遇到GBK字符集里没有的字符直接抛异常。解决方式有三种设置环境变量PYTHONIOENCODINGutf-8在脚本开头调用sys.stdout.reconfigure(encodingutf-8)或者更稳妥地用pathlib.Path统一处理路径不直接print原始字符串。我最后选择的是两种组合日志模块里强制指定UTF-8同时给所有文件名做一层“安全显示”处理把不可打印字符替换成转义形式。这类问题之所以值得单独提是因为它极具隐蔽性跑demo时数据量小文件名都是自己创建的完全不会出错到了离线上千小时的视频集只要有一两个文件名异常训练管线就会在日志打印那一步中断浪费大量GPU时间。工程边界从来不只是模型性能还包括这些细枝末节的稳定性。4. 常见问题与排查技巧实录4.1 复现性两次推理结果不一致怎么办神经Codec项目最容易在复现性上翻车。模型明明设置了随机种子两次压同一帧却得到不同码流或者在评估时BD-Rate抖得很厉害。常见的元凶是cuDNN的benchmark模式和不确定性算子。PyTorch里torch.backends.cudnn.benchmarkTrue会根据输入形状选择不同算法算法切换就会引入微小差异。我在做正式评测时会用torch.use_deterministic_algorithms(True)固定算子行为并把模型放到CPU做一次基准验证再上GPU跑批量测试。如果项目里用了自回归解码还要注意并行线程的浮点累加顺序。不同的线程调度会导致加法顺序变化虽然最终像素值只差零点几但对误差敏感的下游码率控制有影响。我的经验是把确定性要求写进CI脚本每次跑测评前先校验输出文件的哈希值不一致就直接报警不要在实验结果里裸奔。这里也想多说一句复现性不代表绝对真理但视频编码对码流的确定性要求很高因为你不可能让两部终端解出同一份码流时产生不同的画质和码率计数。4.2 码率控制没有QP旋钮怎么办传统编码器可以通过修改量化参数QP来精确控制输出码率神经Codec没有这个旋钮它只有λ。而λ和最终码率并不是一一对应的它还要看输入内容的复杂度。同一个λ压白墙可能只要0.1Mbps压复杂运动会到2Mbps。所以实际工程里我一般离线训练5到7个不同λ的模型做一个“码率档位表”。推理时先根据目标码率和当前内容的复杂度选出最近的λ如果偏差超限再用小步长在相邻模型间做“模型插值”。也有更高级的条件化方案用一个网络根据目标码率直接生成模型参数但那训练成本更高。现阶段最稳妥的还是多模型多档位配合码率统计反馈。如果你只想要“大致符合预期”也可以先跑一遍整段视频再根据实际比特数微调λ后重新压。在离线场景下这种两遍式处理很实用因为这些模型的编码时间本来就以分钟计多跑一遍反而可控。4.3 兼容性模型更新后旧码流怎么办神经Codec的码流格式和模型权重强绑定。训练了一代新模型参数学到的分布变了解码端如果还拿旧模型去解结果一定会崩溃。这意味着你不能像H.265升级到H.266那样靠解码器支持新旧标准来过渡。工程上只能做“版本化的解码器栈”把模型文件、推理引擎版本、甚至预处理参数都打包成一个解码器版本码流头部写清楚版本号。我在团队里的做法是建一个内部模型注册表每次发布新模型都会生成对应的编码器prefix和兼容矩阵。码流的容器格式里加了一个4字节的codec_id字段解码器拿到之后先查注册表确定是否支持不支持就返回一个明确的错误码而不是硬解出花屏。对老码流的兼容则采用双轨部署新旧两套编码方案同时服务一段时间等所有存量流量自然过期后再下线旧模型。这个方法简单但确实能解决最头疼的生态问题。5. 神经视频编码的适用边界与选型建议5.1 哪些场景适合现在就用神经视频编码现阶段最适合两个方向一是短视频和UGC内容的云端转码。这类场景允许离线一次编码、多次分发编码端慢一点没关系解码端只要在服务端预制好GPU用户端只是拉流延迟压力不大。二是有损压缩但需要极低码率的监控视频归档模型在低码率段的画质优势通常比高码率段更明显能省下大量存储成本。反过来直播、会议之类的低延迟场景我不会建议直接替换传统硬编解码器。神经Codec的解码时延和模型下发成本都还达不到实时通讯的工程要求。一个可落地的过渡方案是“神经增强传统压缩”先通过神经网络做降噪、去块、超分预处理再把干净的画面交给H.265硬编这样既能吃到一部分深度学习红利又不牺牲端到端时延。5.2 开源工具链怎么选如果从零开始做我建议先试CompressAI。它基于PyTorch把超先验、自回归上下文、熵编码器都封装好了代码结构清晰适合用来复现论文和做对比实验。视频方向可以关注Mink这类开源方案但更新速度不稳定需要自己维护。不要一开始就追最前沿的SOTA模型先把一个最简单的超先验模型跑通理解loss曲线、码率估计、量化模拟之间的关系比多跑几个模型更重要。动手的时候有几个经验可以参考数据集用Vimeo-90K方便但最好再加一个与你业务场景相关的私有集训练时固定patch大小和裁剪策略评估时统一用YUV 4:2:0格式别拿RGB直接比PSNR。这些看起来琐碎实际决定了实验结果是否能和同行的数据对齐。5.3 我最后想说的三个“非技术”提醒第一个提醒不要迷信论文里的BD-Rate数字。同样的模型换一组测试序列、颜色空间、帧率结果可能差出十几个百分点。第二个提醒工程化时先把数据管线做到万无一失。特殊字符、路径权限、磁盘碎片这些看起来和模型无关的问题才是真实训练过程中消耗最多时间的地方。第三个提醒先想清楚码流生命周期再做架构设计。模型可以快速迭代但你压出来的一百万段老码流要怎么解这个决策要前置到系统架构里否则迟早返工。我个人在实际操作中的体会是神经视频编码并不是要立刻替代H.266而是给了我们一种全新的“压缩视角”把编码效率从人类设计师的上限中解放出来。哪怕是目前只能用在离线场景工程层面的价值也已经很明确。如果你想动手从复现一个超先验模型开始成本比想象中低得多关键是别忽略那些看似和模型无关的工程小事。特殊字符错码、路径处理、随机种子固定这些细节才是从demo走向产品的真正分水岭。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。