他山之石。
经典解码链路已经站在理论边上:匹配滤波在已知波形上是最优检测,LDPC 置信传播是近最优纠错。在这之上做深度学习,先要回答一个问题——哪里还有空隙。这篇文章写下我们量到的空隙、撞上的三堵墙,以及撞墙的准确位置,为的是换来同行的一句话。
这件事最有价值的产出不是模型,是三张表:一张说靶子在哪,一张说墙有多硬,一张说我们没测什么。三张表都能被复算,也都能被推翻。
靶子在低信噪比,不在重叠
三张表定下后面所有设计,没有一张出自偏好。
FT8 是一种 8-FSK 的弱信号模式:79 个符号、每符号 0.16 秒,数据经 (174, 91) 的 LDPC 码编码,整段信号 12.64 秒,装进 15 秒的时隙。解码链路分四步:同步搜索、 音调软值、置信传播、CRC 与呼号结构过滤。第一步先问,这条链路还有多少可捡。
我们把与配置有关的旋钮逐个扫过:profile、cycles、sensitivity、低门限,凑成十个 配置,在同一份真实语料上跑并集。结论是并集不再增长——十个配置的并集里, 最深的那个单配置已经拿到 98.8%。
150 槽真实语料、2936 条报文。此前线上的配置召回 95.2%,三配置组合 99.1%, 最优单配置 100.0%(对可靠参照集,即至少两个配置都认得的报文)。 想再往上,只能换输入或换判据,调参没有余量了。
换判据不可能:解码器是产品的一部分,也是唯一可信的裁判。那就只能看输入—— 弱信号到底丢在哪一段。我们搭了一台仿真器(下一节讲它凭什么可信),把合成信号 放进真实噪底,扫信噪比。
| 标称信噪比 | 快路径召回 | 深配置召回 |
|---|---|---|
| −26 dB | 6% | 31% |
| −24 dB | 19% | 63% |
| −22 dB | 56% | 100% |
| −20 dB | 81% | 100% |
真实语料的解码信噪比分布里,−18 dB 及以下占 10.0%,−20 dB 及以下占 2.9%。 悬崖边上确实有人,−26 dB 处有 69% 的信号被漏掉。
有一件事与直觉相反,值得单说:我们本以为同频重叠是靶子。每槽平均有十六对信号 处在时间重叠、频差 25 Hz 以内,听起来正是经典链路会互相抢的场景。实测下来, 深配置已经拿到并集的 98.8%——链路内部那九趟减除(先解、再减掉、再解)就是为这个 设计的。这里没有多少可捡。
同频重叠有人管,强信号有人管,唯一没人管的是信号的绝对强度低于检测门限那一段。 这一段没有技巧可用,只有理论:能不能从更长的相干积累里把能量攒出来。
标签取自编码器本身
仿真要可信,先得让标签与空中的信号出自同一处。
训练需要(噪声,干净信号)成对的数据。我们不去重写 FT8 的打包规则——那会变成 第二份标准,训练目标漂移就从此开始。做法是让编码器自己给出答案:调用底层 编码接口生成一段干净波形,逐符号做八个音调的离散傅里叶系数,取出每个符号最强的 那一个,逆着格雷映射读回 174 比特码字。没有噪声,没有解调误差。
有一件事在做的过程中才明白:这套码有两张校验矩阵,都对,但用途不同。
| 矩阵 | 来源 | 每行重量 | 用途 |
|---|---|---|---|
稠密 H = [G | I] |
编码器源码中的生成矩阵 | 约 45 | 验证:H·c = 0 |
| 稀疏 Tanner 图 | 解码器源码中的表,每比特三个校验 | 7 | 译码:置信传播与图注意力 |
我先拿稠密那张去跑译码,结果很奇怪:校验满足数在下降,误比特率却在上升 (42 降到 36,12.2% 升到 16.2%)。这是解码器的图不是码的图的典型症状——最小和 算法定义在稀疏图上,稠密表示只是同一个码的另一组基。换成解码器自己那份表, 置信传播立刻正常:σ=0.7 时误比特率 0.0018,整码字全对率 97.2%。
噪声不是白噪声,是真实槽的噪底:真实的大气噪声、衰落与带内干扰。忙槽先在 时频域里把已解出的信号陷波减掉 34 dB 再当噪底——不这么做,别人电台的信号会进 「噪声目标」,模型学到的第一件事就是压制真实信号(这一条后来真的发生了)。 信噪比定标也实测过:白噪底上标称与解码器报告值吻合到 1 dB 内;真实噪底上报告值 系统性高 3 dB,来自非平稳噪声下的比值偏差。
判据是同一把尺:合成信号的信噪比—召回曲线,加上真实语料上的并集增量与精度检查。 后面每个方案都要在这两把尺上对拍同一份数据。
三次尝试,三次撞墙
每一堵墙都有可复现的特征值,不是印象。
第一堵:纯解调器注定追平
第一个模型是集合预测式的:输入整个时隙的复时频图,输出若干查询,每个查询给 存在与否、频率、时延与 174 比特码字。相位必须保留——低信噪比下的判据来自相干 积累,丢掉相位等于把可用能量砍掉一半。
架构上踩了两个坑,都由「看数据」抓出来。其一,预测头在所有符号上做了平均池化, 顺序信息被抹掉,模型卡在 65% 比特准确率上不动;改成逐符号输出三个比特之后 立刻开始学。其二,短时傅里叶的帧格是 40 毫秒,符号是 160 毫秒,而信号的起始 时刻可以落在任意位置,于是每四个帧组成的一组会横跨两个符号——即使信噪比 +10 dB,用最朴素的取最大值也读不出音调。
修好之后训练正常,比特准确率九成七。报文级的产出却是零。
| 信噪比 | 模型整码字 | 经典解码器 |
|---|---|---|
| −26 dB | 0/30(比特 74.3%) | 13/30 |
| −24 dB | 0/30(比特 81.1%) | 22/30 |
| −22 dB | 0/30(比特 88.6%) | 28/30 |
| −20 dB | 0/30(比特 93.7%) | 30/30 |
原因可以算清楚。−20 dB 处比特准确率 93.7%,而一条报文要求 174 个比特全对: 0.937 的 174 次方是一万分之一。经典链路在那里靠 LDPC 纠错拿到约 10 dB 的编码 增益,模型一点没沾上。
九成七的准确率,一条报文也出不来。
准确率是个误导性的指标。它对 174 个比特一视同仁,而报文要求的是全对;两者 之间的差距,正是纠错码存在的理由,也是逐比特目标永远补不上的那一块。
第二堵:把码结构写进损失
既然逐比特不行,就把「是不是合法码字」直接写进损失。这件事有个可微的形式:每个 校验是它所连比特的异或,于是校验成立的概率可以用软异或写出来。
我试了两种写法,最后没能得到一个可信的实现。
| 形式 | 数值行为 | 梯度 |
|---|---|---|
| 符号—幅值软异或 | 有效码字 0.05,翻一位 0.98,随机 0.5(等于 0.693) | 1e-19(该版本) |
| LDPC 的 tanh 规则 | 两次重写后数值互相矛盾 | 未能验证 |
第一版报出 1e-19 量级的梯度。第二版换成文献里的 tanh 规则,同一份输入直接算得 0.5,走模型路径却算得 2.98——两次重写的数值自相矛盾,说明问题在我的实现里, 不在这个思路里。所以这一条我们只记为「实现失败」,不敢当作结论。
量不出梯度的地方,先怀疑自己的尺子。
第三堵:图注意力译码器
第三条路把译码独立成一个组件:输入 174 个对数似然比,输出精炼后的似然比, 注意力的掩码就是 Tanner 图——共享校验的比特互相可见,图的注意力恰好就是消息传递。 这样模型不必从零学码结构,只需要精炼。
基线先修好(就是前面那张稀疏图的教训)。修好后的置信传播很强:σ=0.7 时误比特率 0.0018、整码字 97.2%;σ=0.8 时 0.0321、整码字 65.2%。
| σ | 裸判决 | 置信传播 | 神经译码器 |
|---|---|---|---|
| 0.70 | 0.0759 | 0.0018 | 0.0759 |
| 0.80 | 0.1074 | 0.0321 | 0.1073 |
| 1.00 | 0.1591 | 0.1421 | 0.1592 |
神经译码器的输出不等于输入,它把输入放大了两倍。逐比特符号一致率 99.88%, 误比特率 0.1058 对 0.1059——决策几乎一个没改。它学到的是一条标度增益。
对数似然比的尺度是人为约定,硬判决与它无关;而训练用的交叉熵对尺度敏感。 放大两倍会让损失略微下降,于是模型找到了这条捷径:不改善解码,却降低损失。 从身份到完美输出,损失还有 0.299 的下降空间,优化器没有走进去。
这个实验跑了八千步、五十分钟、八十万参数,而同类工作在文献里用十的五六次方步 加各种编码技巧。我们的判断是:这条路的成败还没被证伪,但已经被证明不可能在 本机的时间尺度上判断。
账写在卡上,不写在感觉上
四个坑,每个都能复现一次,都值一条测试。
第一个坑是算力放错了地方。单样本数据生成要 46 毫秒,而一批十六个样本的训练步 161 毫秒——数据生成是训练的四点五倍。这意味着租来的图形卡有八成时间在等 CPU。 两处改动把它降到 133 毫秒:线程池(重活都释放全局解释器锁),以及把码字缓存起来 (原本每个样本都要重跑一次编码加音调回读,二十到四十毫秒,纯浪费)。 单步从 771 毫秒降到 133 毫秒,瓶颈回到卡上。
第二个坑是符号约定。训练用的损失把「输出大于零」解释成比特一,而似然比的约定是 「大于零为比特零」——两个约定相反,模型学成了把整个信道取反。
误比特率 95.2%,而裸判决是 4.8%。一减,正是它的指纹。
没有基线那一列对照,这个错误会被读成「模型很差」,而不是「约定反了」。
掩码张量必须注册成模型缓冲区,否则在图形设备上第一批就报设备不匹配。 被关掉的损失项必须不计算,不能乘以零——零乘非数是非数,一个默认关闭的项 会因此让整个训练发散。
算力估算也一并写下来,供同样处境的人参考:整槽输入的集合预测模型,在这台八核 笔记本的图形处理器上约 4.8 秒一步,十万步要五天半;换成一张 24 GB 的台式卡, 估计每步 0.15 到 0.3 秒,四到八小时。差的不是一点半点。
我们要的不是算力,是经验
下面每一问都带着上面的实测,省掉同行的复现成本。
先说我们的判断,欢迎反驳。学习只能从经典链路站不到的地方进场:单信号白噪声下, 匹配滤波加置信传播已经站在理论边上。纯解调器的学习版本注定追平,不值得投入。 真正可能赢的地方只有两处——图结构上的学习型译码器,以及多信号的联合检测与分离, 因为经典链路是逐候选贪心的。
① 码结构怎么进损失
可微的软异或与 tanh 规则我们都试过,都没能得到可信的实现。文献里的再编码、 展开置信传播、学习阻尼系数这几条路线,在短码加已知图的条件下哪条最稳? 有没有我们没意识到的标准做法?
② 架构怎么选
在 174 比特加已知 Tanner 图这个规模上,图注意力 transformer、展开的置信传播、 或者经典置信传播配一个学习先验(比如学习似然比修正),哪条性价比最高? 我们是否需要 transformer,还是展开的置信传播就够?
③ 端到端值不值得做
如果学习的价值只能来自非白噪声场景(衰落、多用户、干扰),判据应该怎么设计? 我们手上有两千多槽真实音频和精确仿真,能构造哪些经典必输的场景?
④ 数据效率与域迁移
我们实测过合成信号训练会压制真实信号(增强份丢两成),也实测过把真实信号 重生成进训练目标并无改善。在真实样本上千、仿真无限且标签精确的条件下, 迁移最有效的做法是什么?
⑤ 似然比从哪来
原生解码链路不对外提供软信息。选项是主机侧自建音频到似然比的解调,或者让 学习型链路内部闭环。有没有第三条路,比如让模型只做候选排序与前验修正?
⑥ 算力怎么花
如果只搏一次:整槽集合预测模型十万步、一张 24 GB 卡四到八小时,值不值? 还是同样的预算花在更小更对症的对照实验上(比如第一、二问)更划算?
我们没有在图形卡上训练过任何模型,算力估算全是外推;没有把学习型译码器接入 产品链路,也没有跑过任何真机上的端到端学习解码;没有证明图注意力译码器达不到 置信传播的水平,只证明了本机时间尺度上达不到;没有验证过非白噪声场景下学习 能否取胜,那正是我们想请教的方向;没有做多信号联合分离的任何实验。 把码结构写进损失这件事,我们连一个可信的实现都没做出来——那一节请当作失败记录读, 不要当作结论。
留下的东西比结论多
负面结果也是资产,前提是它可复算。
这一轮真正留下的是四样可复用的东西,与成败无关。
精确的标签管线
报文到波形到码字,全程由编码器自己给出,仿真数据无限、标签精确到比特。 同步图案被写成了测试:它是整条链对齐的唯一无歧义证人。
两套已验证的校验矩阵
稠密的用于验证码字,稀疏的用于译码,两者都从编解码器的源码里解析出来, 并用编码器自己的输出交叉验证——任何一份漂移,测试就会红。
一个正确的置信传播基线
附带它该跑在哪张图上这条教训。没有这条基线,前面那张「95.2% 等于一减 4.8%」 的表就只是噪声,读不出符号约定的错误。
经典链路的实测天花板
从 −26 dB 的 31% 到 −20 dB 的 100%,以及十配置并集等于单配置的事实。 以后任何更聪明的想法,都要先对拍这条曲线。
先说结论再举证,是这类文章最容易犯的毛病。我们尽量反过来:每一句主张背后 都有一张表,每张表都能被重跑。所以这篇的标题借了《诗经》里那句——他山之石, 可以攻玉。石头在手上,问题是怎么切。
研究之外,这一轮有两处已经上线并稳定运行:解码配置的组合搜索把召回推到 可靠参照集的百分之百,两段式发布让界面提前 2.4 秒看到解码(快路径先发, 深答案到达后覆盖同一槽,状态机永远只吃完整的那一份);掩蔽增强以 0.7 的 噪声保底系数挂在主机侧,净增 0.5% 到 0.9%,与原始份并集,只增不减。