Loading...
Loading...
DeepFRI 的 TensorFlow 到 PyTorch 转换与昇腾 NPU 迁移 Skill,适用于蛋白质功能预测场景下的 TF 模型分析、PyTorch 重写、权重逐层映射、NPU 推理与精度验证,尤其适合需要在 Ascend 上运行 DeepFRI CNN 或 GCN 路径时使用。
npx skill4agent add ascend-ai-coding/awesome-ascend-skills ai-for-science-deepfri| 项目 | 要求 |
|---|---|
| 硬件 | Ascend910 系列(至少 1 卡) |
| CANN | ≥ 8.2(推荐 8.3.RC1) |
| Python | 3.10 |
| PyTorch | 2.5.1 |
| torch_npu | 2.5.1 |
cd /home/panjingxu
git clone https://github.com/flatironinstitute/DeepFRI.git
cd DeepFRI
# 下载 GPU 版预训练模型(README 精度参考值基于此版本)
wget https://users.flatironinstitute.org/~renfrew/DeepFRI_data/trained_models.tar.gz
tar xzf trained_models.tar.gz注意:官网提供两个版本:
(GPU 版):CNN + MultiGraphConv + CuDNNLSTM,README 精度参考值基于此trained_models.tar.gz (CPU 版):CNN + GraphConv + 标准 LSTM,结构不同、goterms 数量不同newest_trained_models.tar.gz
export PIP_INDEX_URL=https://repo.huaweicloud.com/repository/pypi/simple/
conda create -n deepfri_npu python=3.10 -y
conda activate deepfri_npu
# TF(仅用于权重提取,可选)
pip install tensorflow numpy==1.26.4 biopython scikit-learn
# PyTorch + NPU
pip install torch==2.5.1 torch_npu==2.5.1
pip install pyyaml decorator attrs psutil cloudpickle tornadosource /home/Ascend/ascend-toolkit/set_env.sh
python3 -c "import torch; import torch_npu; a = torch.randn(3,4).npu(); print(a+a)"import h5py
f = h5py.File('trained_models/DeepFRI-MERGED_xxx.hdf5', 'r')
mw = f['model_weights']
for layer_name in mw.keys():
grp = mw[layer_name]
def print_ds(name, obj):
if isinstance(obj, h5py.Dataset):
print(f" {name}: {obj.shape}")
grp.visititems(print_ds)
f.close()scripts/SKILL_DIR=/path/to/awesome-ascend-skills/ai-for-science/models/deepfri/scripts
REPO_DIR=/path/to/DeepFRI # 替换为实际路径
# 复制 PyTorch 模型文件到 deepfrier 包内
cp $SKILL_DIR/torch_layers.py $REPO_DIR/deepfrier/
cp $SKILL_DIR/torch_model.py $REPO_DIR/deepfrier/
cp $SKILL_DIR/torch_predictor.py $REPO_DIR/deepfrier/
# 复制脚本到仓库根目录
cp $SKILL_DIR/convert_weights.py $REPO_DIR/
cp $SKILL_DIR/predict_npu.py $REPO_DIR/
cp $SKILL_DIR/verify_accuracy.py $REPO_DIR/cd $REPO_DIR
python convert_weights.py
# 生成 trained_models/pytorch/*.pt| 文件 | 目标位置 |
|---|---|
| |
| |
| |
| |
| |
| |
source /home/Ascend/ascend-toolkit/set_env.sh
# CNN 序列输入(对应 README Option 2)
python predict_npu.py \
--seq 'SMTDLLSAEDIKKAIGAFTAADSFDHKKFFQMVGLKKKSADDVKKVFHILDKDKDGFIDEDELGSILKGFSSDARDLSAKETKTLMAAGDKDGDGKIGVEEFSTLVAES' \
-ont mf --verbose --device npu:0
# CNN fasta 输入(对应 README Option 3)
python predict_npu.py \
--fasta_fn examples/pdb_chains.fasta \
-ont mf --verbose --device npu:0python verify_accuracy.py| TF | PyTorch | 转换 |
|---|---|---|
| | 转置 |
| | 直接复制 |
| TF | PyTorch | 转换 |
|---|---|---|
输入 | 输入 | 前后 transpose |
| | |
| | 直接复制 |
| TF | PyTorch | 转换 |
|---|---|---|
| | 直接复制 |
| | 直接复制 |
| | 直接复制 |
| | 直接复制 |
| 默认 eps = 1e-3 | 默认 eps = 1e-5 | 必须设 |
⚠️ 致命 Bug:TF BatchNorm 默认,PyTorch 默认eps=1e-3, 差 100 倍。当eps=1e-5含接近 0 的值时,错误 eps 导致除零爆炸, softmax 饱和为 0/1,模型输出全为 0。这是本次 CNN 迁移中最关键的发现。moving_variance
| TF CuDNNLSTM | PyTorch nn.LSTM | 转换 |
|---|---|---|
| | 转置 |
| | 转置 |
| | 前半 + 后半拆分 |
pt_weight_ih = tf_kernel.T
pt_weight_hh = tf_recurrent_kernel.T
pt_bias_ih = tf_bias[:4 * H] # 前半:input-hidden bias
pt_bias_hh = tf_bias[4 * H:] # 后半:hidden-hidden bias| 测试用例 | GO term | 官网参考值 | NPU 输出 | diff | 状态 |
|---|---|---|---|---|---|
| Option 2: seq→mf (1S3P-A) | GO:0005509 calcium ion binding | 0.99769 | 0.99769 | 5e-6 | ✅ PASS |
| Option 3: fasta→mf (1S3P-A) | GO:0005509 calcium ion binding | 0.99769 | 0.99769 | 5e-6 | ✅ PASS |
| Option 3: fasta→mf (2J9H-A) | GO:0004364 glutathione transferase | 0.46937 | 0.46936 | 9e-6 | ✅ PASS |
| Option 3: fasta→mf (2J9H-A) | GO:0016765 transferase activity | 0.19910 | 0.19913 | 2.6e-5 | ✅ PASS |
| Ontology | 状态 | Top 预测 |
|---|---|---|
| MF | ✅ OK | GO:0005509 score=0.99769 (calcium ion binding) |
| BP | ✅ OK | GO:0051179 score=0.14491 (localization) |
| CC | ✅ OK | GO:0005829 score=0.23145 (cytosol) |
| EC | ✅ OK | 无超过阈值的预测(该蛋白非酶,符合预期) |
newest_trained_models.tar.gz| 文件 | 行数 | 说明 |
|---|---|---|
| 199 | PyTorch 版图卷积层(MultiGraphConv, GraphConv, SAGEConv, NoGraphConv, ChebConv, SumPooling, FuncPredictor) |
| 124 | PyTorch 版模型(LSTMLanguageModel, DeepFRIGCN, DeepCNN) |
| 178 | PyTorch 版推理预测器(PredictorPyTorch,兼容原始 TF 版接口) |
| 147 | TF HDF5 → PyTorch state_dict 权重转换(LSTM/GCN/CNN) |
| 46 | NPU 推理入口脚本(含 |
| 72 | 精度对比验证脚本(对比官网 README 参考值) |
transfer_to_nputorch.cuda.*torch.npu.*import torch_npu
from torch_npu.contrib import transfer_to_npu
from deepfrier.torch_predictor import PredictorPyTorchh5pymodel_weights(8*H,)(in, out).Tnp.transpose(w, (2,1,0))_normalizedef _normalize(self, A, eps=1e-6):
# 去除自环
A = A.clone()
diag = torch.diagonal(A, dim1=-2, dim2=-1)
A = A - torch.diag_embed(diag)
A_hat = A + eye
deg = A_hat.sum(dim=2)
D_asymm = torch.diag_embed(1.0 / (eps + deg))
D_symm = torch.diag_embed(1.0 / (eps + deg.sqrt()))
# 返回三路:[原始A, 非对称归一化, 对称归一化]
return [A, D_asymm @ A_hat, D_symm @ A_hat @ D_symm]# BatchNorm eps 必须匹配 TF 默认值
self.bn = nn.BatchNorm1d(total_filters, eps=1e-3)
# Conv1D 输入需要 transpose
def forward(self, seq):
x = seq.transpose(1, 2) # (batch, length, ch) → (batch, ch, length)
conv_outs = [conv(x) for conv in self.conv_layers]
x = torch.cat(conv_outs, dim=1)
x = self.bn(x)
x = F.relu(x)
x = x.max(dim=2)[0] # GlobalMaxPool
return self.func_predictor(x)1e-31e-5nn.BatchNorm1d(dim, eps=1e-3)load_modelCuDNNLSTM(batch, length, channels)(batch, channels, length)h5py(8*H,)padding='same'references/weight-conversion-checklist.md