来源:research/paper-reading/HPCM_代码阅读指南.md · 原始 Markdown
HPCM 代码阅读指南
官方仓库:https://github.com/lyq133/LIC-HPCM
本地位置:E:\Projects\research\LIC-HPCM
本次检查版本:c271cfe2412071e7cacf4186825f1bbff4434664。已拉取源码并静态检查,尚未安装依赖、下载权重或运行官方模型。以下行号对应此版本。
先看哪个模型
先看 src/models/HPCM_Base.py。其中有分层编码和 CrossAttentionCell,可以对应论文中的两项主要设计。
HPCM_Base_PhiContext.py 是另一个上下文变体:其 forward_hpcm 直接将熵参数网络输出赋给 context_next,没有 Base 中的交叉注意力更新。README 也专门提到这个版本及 issue #3。阅读时不要把两个实现混起来。
HPCM_Large.py 和 HPCM_1B.py 暂时跳过;后者属于仓库增加的后续扩展工作。
第一遍:从输入到输出
打开 src/models/HPCM_Base.py:199,看 HPCM.forward:
y = self.g_a(x):把图像转换为潜变量。z = self.h_a(y):从潜变量提取超先验侧信息。- 得到量化的
z_hat,并计算其 likelihood。 params = self.h_s(z_hat):生成后续概率估计所需的参数信息。forward_hpcm(y, params, ...):分层处理潜变量,得到重建潜变量及概率分布尺度。x_hat = self.g_s(y_hat):重建图像。- 返回重建图和 y、z 的 likelihood,供损失计算。
第一次不用逐层研究卷积,只要分清 x、y、z、y_hat、x_hat 分别是什么。
第二遍:对应论文图2的分层编码
打开 src/models/HPCM_Base.py:236,看 forward_hpcm。
get_s1_s2_with_mask:按 mask 选择元素并重新排列成较小尺度。实现位于src/models/base.py:334,不是插值缩图。- S1:
for i in range(2),新增两个编码步骤。第一步只使用超先验提供的信息。 recon_for_s2_s3:把较小尺度的值填回较大尺度对应位置,见base.py:344。- S2:mask 列表使用
[1:],新增三个步骤。 - S3:mask 列表使用
[2:],新增六个步骤。
代码注释中的 4-step、8-step 容易误导:较大尺度中有一部分已经由较小尺度编码,所以新增步骤总数为 2 + 3 + 6 = 11。
重点跟踪 y_hat_so_far:它汇总当前已经重建的潜变量,后续步骤依赖这些已知值估计概率。这就是我们讨论的解码先后约束。
第三遍:对应图3和图4的渐进融合
打开 src/models/HPCM_Base.py:136,看 CrossAttentionCell.forward。
x_t提供 Q,h_prev提供 K、V。q @ k计算匹配分数;softmax 得到权重;权重与 V 相乘完成信息汇总。- 输出加上当前状态经过卷积的结果,形成新的上下文。
- 代码先使用
rearrange分窗口处理注意力,不是直接对整个潜变量网格做全局注意力。
回到 forward_hpcm,寻找:
params = torch.cat((context_next, y_hat_so_far), dim=1)
context = y_spatial_prior_s1(...)
context_next = self.attn_s1(context, context_next)
scales, means = context.chunk(2, 1)
其中 context 是本步熵参数网络的输出,context_next 保存融合后的上下文。S2、S3有相同形式的更新。跨尺度则通过位置回填、超先验补充和 context_net 连接。
最后再看训练和真实编码
train.py:36 的 RateDistortionLoss:对 y 和 z 的 likelihood 计算负对数,得到估计 bpp;再加上 lambda × 255² × MSE。
test.py:82 的 test:加载权重并更新概率表,调用 compress 与 decompress。这里的 bpp 使用返回字节串长度计算,不是训练时的 likelihood 估计。默认测试流程把图像补齐到256的倍数,再裁回原尺寸。
src/entropy_models/entropy_models.py:40 的 GGM:概率估计与编码概率表相关实现。第一遍可以先跳过内部 CDF 和底层 rANS 代码。
当前机器的运行注意点
仓库 README 标明 Python 3.8、PyTorch 1.12,并附带 Linux / CPython 3.8 的 .so 熵编码扩展。当前 Windows 教学环境是另一套版本,不代表官方代码已可运行。
具体检查到:
entropy_models.py:7在导入时就需要_CXX扩展,不能仅凭“不生成码流”便认定可以绕过所有原生依赖。HPCM_Base.py构造参数时指定device='cuda',test.py也明确使用 CUDA。- requirements.txt 包含多个深度学习框架和许多旧版依赖;正式配置环境前应梳理实际依赖,不宜直接装入现有教学环境。
今天的阅读目标
只看 HPCM.forward 与 RateDistortionLoss,能回答:图像从哪里进入、潜变量如何产生、重建图如何生成、压缩码率如何参与训练。下一次再看分层 mask 和交叉注意力。无需一次读完整个仓库。