先从一段报错说起。前阵子处理一批文本日志,Python 在写文件时直接抛了一行:
UnicodeEncodeError: 'gbk' codec can't encode character '\ue687' in position 42...我第一反应是换编码,把输出编码改成 UTF-8 就绕过去了。顺着这个报错往下想,倒是想起一件挺多人会搞混的事:"Codec"这个词在计算机世界里扛着两副完全不同的担子。一副是字符编码,负责把字符串变成字节流;另一副是媒体编码,负责把视频像素压成码流。前者往往只是映射表加几个转义规则,后者才是真正意义上"又编码又解码"的压缩引擎。上面这个报错里的 codec 是前者,而我今天想聊的神经视频编码,是后者。
神经视频编码这几年在学术界和工程圈的声量越来越大。一句话概括:它试图把传统视频编码里那些由人设计了几十年的规则,替换成从数据里学出来的神经网络。听起来很性感,但真正把它往生产线上一放,会撞上一堆和"压缩率"无关的边界问题。这篇东西,我想把神经视频编码背后的技术逻辑拆开讲清楚,再把工程上那些绕不开的边界一条条摆出来,给准备入坑的同学一个参考。
1. 先从那个 GBK 报错聊起:同样是 Codec,字符映射和像素压缩完全是两回事
1.1 那个报错到底在说什么:字符编码的职责边界
'\ue687'这个字符很有意思,它在 Unicode 里落在"私有使用区"(Private Use Area)这一段。私有区说白了就是留给特定系统、特定字体自己去定义的字符,不像汉字、拉丁字母那样有全球统一的语义。而 GBK 是面向中文环境设计的编码表,它只给有限的码位分配了映射关系,\ue687在 GBK 里压根没有对应关系,于是编码器当场抛错。
这个场景里,codec 的工作本质是"查表映射":字符集定义每个抽象字符的编号,编码表把这个编号再映射成具体字节。映射不到就失败,几乎不存在"压缩效率"一说。这也是为什么字符编码的问题通常很好解决——换个容纳范围更大的字符集,比如 UTF-8,多数情况就平了。
1.2 视频 Codec 才是真正的"压缩引擎"
媒体视频领域的 Codec,比如 H.264、HEVC、AV1,职责完全不同。它的输入是一帧一帧的像素画面,输出是一段尽量短、又能被解码器忠实还原的二进制码流。这里要同时面对空间冗余、时间冗余、视觉感知特性,还要考虑码率、延迟、复杂度、容错性,是一整套系统工程。
传统视频编码的框架已经有二十多年历史,大家熟悉的 I 帧、P 帧、B 帧、宏块、DCT、量化参数 QP、熵编码,都是这套框架里的零件。它们的特点是:所有规则都是人写死的。预测模式有哪几种、变换用哪张表、量化步长怎么选、上下文概率怎么建模,标准文本里规定得清清楚楚。
1.3 当我说"Codec 开始学习"时,究竟指什么
"学习"指的是把上面那套人为设计的零件,替换成可以从数据里拟合出来的神经网络。传统编码器的设计逻辑是人类工程师观察大量视频后总结出"像素之间有相关性,相邻帧之间更相关"这类先验,然后把这些先验固化成算法;神经视频编码则希望让模型自己从训练数据里发现冗余结构,并端到端地优化"压缩后码率越小越好、重建后画质越高越好"这个目标。
所以严格说,"Codec 开始学习"这句话的准确含义不是某个视频编码器文件学会了自我更新,而是编码器的设计方法论从"人工写规则"切换到了"数据驱动学规则"。这个切换带来的收益听起来很直接——压缩率可能提升,但代价是整整一面新的工程边界,后面几章会逐一展开。
2. 传统视频编码的"人工规则"基因:神经编码对标的到底是什么
2.1 用了二十多年的混合编码框架:预测、变换、量化、熵编码
传统视频编码被称为"混合编码框架",因为它是多种工具的组合。看一个典型的 H.264/HEVC 编码流程就清楚了:
- 帧内预测:利用当前帧已经编码的邻近像素,推断当前块的内容;方向越多,预测越准。
- 帧间预测:在参考帧里做运动估计,找到当前块的匹配位置,只编码运动矢量和残差。
- 变换编码:把残差从像素域转到频率域,DCT(离散余弦变换)会把能量集中到低频系数上。
- 量化:对变换系数做有损压缩,这是码率下降的主要来源,QP 越小越清晰,QP 越大越省码率。
- 熵编码:用 CABAC 或 CAVLC 对量化后的语法元素做无损编码,利用符号概率分布进一步压掉冗余。
这套框架的每一环都凝结了工程师几十年的调优经验,比如预测方向从 9 种加到 35 种,变换块从 4x4 扩展到 32x32,熵编码从 CAVLC 进化到 CABAC。但它整个的设计基础,是"人对视频信号的先验判断"。
2.2 人工规则的三个"天花板":局部性、离散选择、启发式平衡
第一个天花板是局部性。传统编码基于像素块做预测和变换,块的大小从 4x4 到 64x64 不等,但本质上还是在局部邻域里做文章。语义级别的信息,比如"这个区域是树叶""这段画面在快速旋转",很难被显式建模,最多通过更细的块划分间接逼近。
第二个天花板是离散选择。编码器做决策时面对的是模式集合,帧内选哪种预测、帧间选哪个参考块、是否跳过、是否分割,本质都是有限集合里的穷举。编码器只能不断尝试、用率失真代价函数挑一个最优解,代价是编码器复杂度极高,而且决策空间本身限制了表达能力的上限。
第三个天花板是启发式平衡。率失真优化里那个著名的代价公式 J = D + λR,D 是失真,R 是码率,λ 是拉格朗日乘子。传统编码器里 λ 怎么取、QP 怎么分配、码率控制怎么做,大多是经验公式和查表。H.264 的码率控制查表模型到 HEVC 又得重新设计,AV1 再改一遍,每一代标准都在重复造这套启发式轮子。
2.3 学习式编码的破局点:让整个链路变得可微、可端到端优化
神经视频编码的目标,是把上面这些不可微的、离散的、启发式的环节,换成一层层可以求梯度的神经网络。分析网络负责把图像转换成潜在表征,合成网络负责把潜在表征重建回图像,中间插入一个量化模块,再配一个神经网络熵模型估计码率。整个系统在一个损失函数下联合训练,误差从重建图像一直反传到编码器输入。
这个思路最诱人的地方在于:网络有能力学到远超"局部块预测"的全局表征。它可以把"这张图里有一个人脸""这是快速运动的球赛画面"这类高层语义直接编码进潜在特征里。理论上,它逼近率失真理论最优边界的潜力比手工框架大得多。这也是为什么过去几年顶级会议里,学习式图像编码的 BD-Rate 曲线一路下探,把老牌编码器逼得很难看。
3. 神经视频编码的核心技术逻辑:从"计算像素"到"学习表征"
3.1 一个生成式自编码器如何完成"压缩"
拿学习式图像编码当基准来看,整体结构就是一个自编码器。编码器 f(x) 把像素张量 x 映射成潜在特征 y,量化器把 y 变成离散符号 ŷ,熵编码器把 ŷ 的符号序列压成码流,解码器 g(ŷ) 把符号重建回图像 x'。训练目标是最小化两个东西的加权和:重建失真 D(x, x') 和码率 R(ŷ)。
这里的"码率"并不是真的跑一遍熵编码,而是用一个熵模型来估计每个符号的分布概率。根据信息论,如果知道了符号的边界分布,理想平均码长就是负对数概率,所以损失函数里可以直接用熵模型给出的负对数似然作为 R 的代理。训练完成后,真正的熵编码器(算术编码器)再按这个分布去写码流。整个系统里,编码器和解码器都不是手工设计的变换,而是卷积网络堆出来的。
3.2 时间冗余怎么学:运动建模在神经编码里的两种路线
视频比图像多一个时间维度,直接逐帧按图像压缩,等于抛弃了最肥的冗余。神经视频编码处理时间冗余大致有两条路线。
一条是"混合路线":沿用传统编码的思想,先做运动估计和运动补偿,把参考帧对齐到当前帧,然后用神经编码器压缩残差。OpenDVC 和不少早期工作都是这个路子,运动信息用传统光流或者轻量网络估计。
另一条是"隐式运动路线":不显式算运动矢量,而是把参考帧和当前帧一起喂给网络,让网络自己决定怎么利用时间相关性。典型做法是把参考帧的特征和当前帧提取的特征做融合,甚至引入循环网络把时间状态一路传递下去。
实际效果上,显式运动建模在低码率大运动场景下更可控,隐式方案在复杂非刚性形变时更灵活。但不管哪条路线,运动信息本身要花多少码率、特征空间里怎么对齐,始终是核心矛盾,这也是神经视频编码比神经图像编码难做一截的原因。
3.3 不可导量化与熵模型:论文里最绕、工程上最刺激的部分
量化是一个天生不可导的操作。把连续浮点特征 y 映射到离散符号 ŷ,最简单的办法是取整,可取整函数的梯度几乎处处为零,反向传播直接断掉。研究里常用的折中是 STE(Straight-Through Estimator):前向做真实量化,反向传播时假装量化是一个恒等函数,把梯度原样传回去。因为近似性比较大,这些年出现了很多软量化、噪声替代量化、均匀噪声松弛的做法,目的都是让训练时的梯度更接近真实量化路径。
熵模型同样不简单。早期模型假设每个符号互相独立,用一个超先验网络输出均值和方差,实际压缩效率很有限。后来逐步引入自回归上下文模型:解码时一边预测分布一边逐块重建,前面已解码的符号影响当前符号的概率估计,码率省下来了,但解码过程变成了串行操作,延迟大涨。再往后又有"通道自回归"“切片自回归”的改良,本质都是在"上下文丰富度"和"可并行解码程度"之间做取舍。
3.4 率失真优化的"学习版":损失函数里的 λ 野心
传统编码器里,λ 是编码器决策时的代价权重;神经视频编码里,λ 直接变成了训练损失函数的超参数。训练时对一个视频片段反复前向、反向传播,模型在最小化 D + λR 的过程中,学会把"预算"分配给视觉上更重要的区域。人脸区域值得多花比特,平坦天空少花比特,这种分配策略不是靠人工规则,而是靠损失函数逼出来的。
这带来一个工程上的连锁反应:传统编码器换 QP 就能换码率档位,神经网络的 λ 要在训练时就定好,一个模型通常只对应一个压缩效率档位。想要覆盖从低码率到高码率的完整区间,要么训练多个模型,要么使用"可变码率"设计,比如给网络额外输入一个质量调节编码。问题在于,真实视频内容的复杂度波动很大,同样一个 λ,面对镜头复杂的动作片和静止的课堂录播,实际码率可能差别好几倍,在线码率控制基本没法儿用传统思路去套。
4. 工程边界一:压缩效率增长背后的解码器算力账单
4.1 复杂度不对称:编码端重,解码端也并没有轻到哪去
很多人以为神经视频编码是"离线重度编码、在线轻度解码",听上去很适合点播场景,但实际测过之后要冷静一点:解码端虽然比编码端轻,却也是实打实的神经网络前向推理。我自己在消费级 GPU 上跑开源的神经解码器,多数模型只能跑到几十帧每秒,换成纯 CPU 解码,个位数帧率是常态;作为对照,一个优化良好的 H.265 软件解码器在同样机器上跑 1080p 到上百帧并不难。
这个差距在移动端更明显。手机里的视频硬解单元是一块专为 H.264/H.265/AV1 设计的 ASIC,功耗和发热都可以忽略不计;神经解码器要在 GPU、NPU 或者 DSP 上做大量卷积和矩阵运算,能效比差了两个数量级。对"解码器要跑在十亿级终端上"的消费视频场景来说,这个账单目前接不住。
4.2 解码不是"一锤子买卖":内存、延迟与流式访问
神经解码器除了算力,还有一个容易被忽略的问题:状态量太多。传统解码器重建完一帧,参考帧缓存是固定的几块像素;神经解码器要保留中间特征图、循环状态、上下文缓存,显存和内存占用直线上升。云游戏、实时通话这类对端到端延迟极其敏感的场景,每一帧多花几十毫秒都是灾难。
随机访问更是硬伤。传统编码器有 IDR 帧,播放器可以随时跳到任意关键帧开始解码;神经视频编码的特征空间是一个连续的隐向量,很多模型解码当前帧强依赖前一帧甚至前更多帧的隐状态,一旦丢帧,整个特征链全断。做剪辑、拖进度条、丢包重传,全都变得异常痛苦。这也是为什么至今没有哪个流媒体平台敢把神经编码用于常规点播分发——播放体验里最基础的"拖进度条",它就没法优雅支持。
4.3 硬件加速的错位:神经网络算子进不了 ASIC
传统编码标准成熟后,产业链会把这套标准做成专用芯片。用户拿到的是一个能硬解 HEVC 的电视盒子,至于 HEVC 内部怎么做熵编码,用户完全不用关心。神经网络编码的问题在于,网络结构迭代太快,训练时的结构可能下个月就换更新版本了,专用芯片公司根本不敢投片。
更现实的问题是,即使定下一套网络结构,解码端的算子仍然是卷积、矩阵乘、归一化、激活函数,这些在 GPU/NPU 上可以跑,但在传统视频 ASIC 上不存在。想把神经解码器塞进电视芯片,意味着要么重新设计一块专用 NPU,要么把已有 NPU 的性能做大幅预留。在当前没有统一标准的局面下,几乎没有芯片厂商愿意为它押注。
4.4 混合方案的活法:神经后处理先上车,神经编解码殿后
正因为直接端到端替换太激进,工程界更愿意采纳的是"混合方案":传统编码照旧,神经模块用在锦上添花的位置。比如在解码端加一个神经超分辨率模块,把低分辨率码流重建回高分辨率;或者用神经网络做环路滤波,把传统编码产生的振铃、块效应抹掉;再或者用神经后处理提升按需视频的主观画质。
这类方案的共同点是:码流仍然是标准编码器生成的,播放器也仍然认识它,神经网络只是在解码链路里偷偷做了增强,不破坏分发兼容性。很多厂商已经用这套思路在有限场景尝到了甜头。它虽然不是完全意义上的神经视频编码,但它先把"学习"这件事安全地放进了工程链路里,给纯神经编码争取了时间和验证空间。
5. 工程边界二:标准化、兼容性以及"能播出来"这件事为什么这么难
5.1 没有标准,就没有播放器、封装和分发
视频编码能成为今天的基础设施,不是因为压缩率本身,而是因为 H.264、HEVC、AV1 这些标准定义了"码流长什么样、解码器必须怎么解"。有了标准,才有 ffmpeg、VLC、浏览器、手机壳里的硬解单元、CDN 分发体系。任何一个新编码方案,哪怕压缩率再好,只要没有标准化的码流格式和经过验证的参考解码器,就不可能进入主流分发链路。
神经视频编码现在最缺的恰恰就是这套"人见人爱的标准"。论文里的 PSNR 曲线很好看,但那些模型权重、特征布局、熵模型参数,每篇论文都各写各的;把它们的码流交给另一个模型解,立刻变花屏。过去十年学习式图像编码的重要推动就是 JPEG AI 这类标准化尝试,而视频领域还停留在更早的探索阶段,距离正式标准落地依旧很远。
5.2 码流格式与容器:神经网络的权重、特征、熵模型如何装进 MP4
就算不考虑标准,光是把神经编码器塞进现有分发体系,就够工程团队头疼。MP4、WebM 这类容器封装的是传统视频标准的 NAL 单元,里面是量化系数和运动矢量;神经编码器要写进文件的是离散化后的特征张量,甚至可能还要附上熵模型的上下文概率表。容器需要扩展新的 box,解析器需要知道网络版本、特征布局、量化范围、熵模型超参数。
更麻烦的是,解码一个神经码流需要加载神经网络权重文件。权重文件本身就是几十上百 MB,这还没算码流;解码端要先把模型拉下来再开始解,冷启动延迟一下子就上去了。传统视频编码器的解码逻辑是标准里写死的,播放器不需要知道"编码器内部长什么样";神经编码器恰恰相反,解码方必须共享模型结构和权重,这个协作成本和生产链路里的信任成本都很高。
5.3 内容适应性与模型漂移:训练数据的"偏见"
神经网络的一个显著问题是过拟合。训练数据如果以自然风景、人物访谈为主,模型对动画、屏幕录制、监控夜视、医疗内窥镜这些特殊内容的压缩表现就会明显下滑。传统编码器是"规则驱动",无论什么内容都按同一套逻辑处理,哪怕效率低一点,至少不会出现不可控的劣化;神经编码器则可能出现花屏、纹理粘滞、人脸糊成一团这类系统性退化。
更隐蔽的是"模型漂移"。传统编解码器一旦标准化,行为是永久确定的;神经网络模型可以不断重新训练、微调,今天发的解码器权重和三个月后的权重可能不一样。同一段码流在新旧模型上重建出的画面也会不一样,这在质量审片、取证、监控回放这类对一致性有要求的场景里是没法接受的。工程系统讲究确定性,神经网络的非确定性恰恰是它最不受欢迎的地方。
5.4 当前真正落地的场景:可控接收端优先
综合看下来,神经视频编码短期内最适合的场景,都有一个共同点:接收端可控、算力可控、码流不需要与历史生态互通。比如私有链路的云游戏推流,视频从服务器编码、同属一方的客户端解码,中间不经过第三方播放器,模型版本可以强制同步;再比如监控视频摘要、海量视频的离线分析,先把视频压缩成特征域表示,再用同样的模型做结构化分析,压缩和分析可以联合优化。
这类场景不需要兼容 VLC,不需要硬解,也不要拖进度条的用户体验。它们更看重特定内容上的压缩增益和联合业务收益。神经视频编码想要进一步破圈,大概率也是从这个内部闭环开始,而不是直接硬刚通用分发。
6. 跑通神经视频编码器后的实测体会:选型、训练、评估与工程化建议
6.1 开源选型:先跑 CompressAI,再从图像模型切入视频
如果你也想上手实验,我的建议是先别急着找"神经视频编码"的完整代码库,从学习式图像编码开始会平滑得多。CompressAI 是比较好上手的开源项目,基于 PyTorch,里面集成了大量论文的复现模型。直接用官方仓库里提供的预训练权重对测试图片做编解码,看码率、看 PSNR、看解码延时,能非常直观地建立对神经编码的感受。
等图像这条路跑通了,再切到视频相关的实现。OpenDVC 是比较早期的参考,近年也有不少带光流和循环状态的开源实现。把第一段视频压出来、再把重建帧和原始帧做像素对比的那一刻,你会真正明白"特征张量"和"残差系数"的差异,也更能体会到解码延迟和随机访问带来的痛感。
6.2 自回归熵模型是解码延迟的隐形瓶颈
在实测中,解码延迟的大头往往不在卷积网络本身,而在熵编码。图像模型里的自回归上下文模型是逐步解码的,先解码一小块,根据这块的分布再预测下一块,长条形的串行依赖让 GPU 的并行优势完全发挥不出来。视频模型里如果沿用了这个结构,解码一帧的延迟很容易翻倍。
工程上要抠延迟,第一步就是看熵模型是不是自回归的。选用非自回归、只依赖超先验的模型,码率会略涨,但解码速度和并行度立刻改善。如果业务更看重延迟而非极致压缩率,这个交换通常非常值得。
6.3 评估指标的陷阱:PSNR 涨了不等于观感好了
评测神经编码器,不能只看 PSNR。神经网络的优化目标天然偏向"在统计意义上接近原图",人眼容易察觉的纹理细节、边缘振铃、肤色连续性,PSNR 并不能完全反映。实测中有时候 PSNR 比 H.265 高 0.4dB,但主观 A/B 对比时观众反而觉得神经重建的画面"太磨皮""动态纹理发飘"。
建议评估时至少同时跑 VMAF 和主观 MOS 小样本测试,并且素材要覆盖自然风景、体育大动态、动漫、屏幕录制、低光夜景。只拿一套官方测试集说明不了什么问题,尤其在内容的边缘地带,传统编码器的稳定性和神经编码器的不确定性会呈现你想象不到的巨大落差。
6.4 如果非要在生产环境用神经编码,我的建议
如果项目迫不得已必须上神经视频编码,我给你三条实在的经验。第一,采用混合架构,尽量把神经模块放在传统编码链路的旁边而不是替代掉它,这样至少保留了一条可回退、可调试的路径。第二,接收端必须可控,而且一定要提前谈好模型更新策略和失败降级方案,不要假设所有解码端都永远在用同一个权重。第三,设计好灰度观察指标,不要只盯着压缩率,而是同时采集解码耗时、首帧延迟、内存占用、花屏率、用户投诉率,这些才是决定神经编码器能不能活下去的真实数据。
我自己做完这一轮实验的最大感受是:神经视频编码的压缩效率确实已经走到了可以和传统标准扳手腕的阶段,但它从实验室走到真实用户面前,中间的工程鸿沟远比大家想象的宽。这个鸿沟不是靠再叠几层网络就能填平的,它需要标准、芯片、播放器、内容方一起坐进同一张桌子。在那一天到来之前,传统编码链路依旧是视频工程的地基,而神经编码,是做在上述地基上一层层试探未来可能的脚手架。