春江暮客

春江暮客的个人学习分享网站

RFOptimization 实用指南:蛋白质设计优化、环境搭建与结果检查

2026-10-08 技术
RFOptimization 实用指南:蛋白质设计优化、环境搭建与结果检查

设计出的蛋白质看起来合理,仍可能无法通过结构预测指标筛选。RFOptimization(RFO)从已有分子复合物出发,寻找能够改善预测性质的序列变化。本文介绍它的优化流程、如何搭建小规模试跑环境,以及怎样用 Python 检查循环是否完整执行。

资料核对日期为 2026 年 10 月 8 日。方法来自 Zhang 等人的 RFOptimization 预印本,最初于 2026 年 9 月发布。下文安装和模型命令已对照公开源码检查,本文没有运行 GPU 优化,也没有复现论文基准。独立记录检查脚本及其合成示例已在本地测试。

1. RFOptimization 修改什么

RFO 是一种无需额外训练的优化框架:使用预训练模型,不重新拟合一套模型权重。序列优化过程仍然可以使用梯度。预印本将梯度引导的突变搜索、结构预测和 MPNN 序列重设计结合起来,并以 AlphaFold3 作为单独的最终评估工具。文中报告的提升针对计算筛选,不能据此认定每个通过筛选的设计都已获得实验结合证据。参见原始摘要。

公开实现在每轮循环中选择两个分支之一:

阶段 作用
RF3 分支 用 RoseTTAFold3 引导序列优化
Boltz 分支 用 Boltz-2 为当前序列预测结构
外部 MPNN 重新设计 A 链中未固定的残基,将复合物传入下一轮
单独评估 优化结束后,对选出的设计进行独立检查

backprop_fraction: 0.5 表示每轮选择 RF3 的概率。它不保证严格交替执行,也不保证短任务中两个分支各占一半。设为 1 或 0,分别只使用 RF3 或 Boltz 分支;两个分支都保留 MPNN 步骤。

与 FlashPPI 的相互作用筛选不同,这个流程会修改输入设计。保留初始复合物,才能用相同评估流程比较起始序列、每轮生成的序列和最终候选。

2. 准备输入和模型环境

使用配备 NVIDIA GPU 的 Linux 机器,并准备可用的 Conda。驱动程序与 RF3、MPNN、Boltz 分别使用独立环境。以下命令应在同一个 shell 中执行,让导出的路径保持有效。CUDA 兼容性和模型资源要求以安装说明为准。

待设计的蛋白质必须是 A 链,包含标准氨基酸,以及完整的 N、CA、C、O 主链原子。在双蛋白示例中,B 链是结合伙伴。启动前检查链 ID 和残基完整性;RF3 分支通过与 B 链的接触关系确定 MPNN 固定残基。运行 YAML 中的路径相对于当前工作目录解析。参见循环输入约定。

新建工作目录,并固定到本文检查的 Foundry 源码版本:

mkdir rfo-tutorial
cd rfo-tutorial
export RFO_WORK="$PWD"
git clone https://github.com/RosettaCommons/foundry.git
cd foundry
git checkout 94c78ab125c6ef2cc7d1226de86d1bd578bf8bee

conda create -n rfo-driver python=3.12 -y
conda activate rfo-driver
python -m pip install -e '.[rf3,rfo]'
foundry install rf3
export RF3_CKPT="$HOME/.foundry/checkpoints/rf3_foundry_01_24_latest_remapped.ckpt"
rfo --help

RF3 权重需要支持置信度预测,并包含训练配置。安装说明指出,历史研究配置使用过其他权重。这里提供的是软件试跑流程,不代表复现论文实验。模型相关资源请查看 RF3 配置文档。

安装上游 LigandMPNN 仓库。它提供 RFO 调用的 run.py 接口,支持 ProteinMPNN 和 LigandMPNN:

cd "$RFO_WORK"
git clone https://github.com/dauparas/LigandMPNN.git
cd LigandMPNN
conda create -n rfo-mpnn python=3.11 -y
conda activate rfo-mpnn
python -m pip install -r requirements.txt
bash get_model_params.sh ./model_params
export MPNN_REPO="$PWD"
export MPNN_PYTHON="$CONDA_PREFIX/bin/python"
export MPNN_MODEL_TYPE=protein_mpnn
"$MPNN_PYTHON" "$MPNN_REPO/run.py" --help
git rev-parse HEAD > "$RFO_WORK/mpnn-commit.txt"
python -m pip freeze > "$RFO_WORK/mpnn-packages.txt"

根据机器情况处理上游 CUDA/PyTorch 依赖。RFO 的适配器不使用 Foundry 自带的 mpnn 命令。将 Boltz 安装到独立环境,再切回驱动程序环境:

conda create -n rfo-boltz python=3.12 -y
conda activate rfo-boltz
python -m pip install 'boltz[cuda]'
export BOLTZ_EXECUTABLE="$CONDA_PREFIX/bin/boltz"
export BOLTZ_CACHE="$HOME/.cache/boltz"
"$BOLTZ_EXECUTABLE" predict --help
python -m pip freeze > "$RFO_WORK/boltz-packages.txt"

conda activate rfo-driver
cd "$RFO_WORK/foundry/models/rfo"
python -m pip freeze > "$RFO_WORK/driver-packages.txt"

这些命令记录外部 MPNN 的提交版本和已安装包版本,但没有锁定完整依赖图。还应保留权重文件名与校验和、输入结构以及实际运行配置。Boltz 首次使用时可能下载模型资源,应将下载耗时与优化耗时分开记录。

3. 先检查两个分支,再运行混合循环

在 foundry/models/rfo 目录下,使用仓库提供的示例复合物,分别执行两个分支:

rfo --config src/rfo/cycling/configs/example.yaml \
    --backprop-fraction 1 --total-cycles 1 \
    --out-dir outputs/smoke-rf3

rfo --config src/rfo/cycling/configs/example.yaml \
    --backprop-fraction 0 --total-cycles 1 \
    --out-dir outputs/smoke-boltz

每次试跑使用新的输出目录。驱动程序实现会在启动时初始化记录文件;复用目录可能覆盖记录,也可能让旧产物与新产物混在一起。

两次单轮任务成功后,在同一目录将以下内容保存为 tutorial.yaml:

input_structure: ./src/rfo/cycling/examples/example_complex.cif
out_dir: ./outputs/tutorial-mixed
backprop_fraction: 0.5
total_cycles: 3
mpnn_num_seqs: 1
mpnn_temperature: 0.1
seed: 42

运行并查看记录:

rfo --config tutorial.yaml
python -m json.tool outputs/tutorial-mixed/example_complex_records.json

命令行接口允许命令行参数覆盖 YAML 设置;显式填写的 assets: 设置会覆盖环境变量。这个示例使用前面导出的路径,没有添加目标专用 MSA 或模板。没有 MSA 时,Boltz 使用单序列模式;加入目标 MSA 会改变实验条件,需要记录。

这是一个三轮集成试跑,不是适用于所有蛋白质的优化轮数建议,也不构成基准结果。

4. 分清输出对应哪个阶段

对于仓库示例,在 outputs/tutorial-mixed/ 中检查:

产物 检查内容
example_complex_records.json 已完成循环、分支名称、分数、序列和耗时
recycle_1/mpnn/mpnn_spec.json 第一轮 MPNN 固定了哪些残基
recycle_1/mpnn/mpnn_result.json MPNN 序列与传递给下一轮的信息
inputs/example_complex_1.pdb 第一轮结束后传入下一轮的重设计复合物
recycle_1/rf3_config.yaml 选择 RF3 分支时生成的本轮配置

记录中的循环编号从 0 开始,文件夹从 recycle_1 开始。记录中的分数来自本轮 MPNN 重设计之前的结构预测或优化分支;mpnn_sequence 则是之后生成的序列。不能把这些分数直接当作新序列经过独立重新折叠后的评分。这个执行顺序可以在主循环源码中核对。

还有两个容易误读的细节。增加 mpnn_num_seqs 会保存更多样本,但程序仍然将第一个样本传入下一轮,没有对样本排序。另外,Boltz 分支中的 AF3_Status 是沿用的字段名称,不表示运行了 AlphaFold3。应结合 method 字段和实际模型输出判断。独立 AF3 筛选不属于这个流水线。

5. 用 Python 检查已完成循环

下面的脚本只依赖 Python 标准库。它检查循环数量、连续编号、分支名称、标准氨基酸序列、链长度一致性,以及耗时是否为有限非负数。脚本不检查坐标,也不解释置信度评分。

下载 check_rfo_records.py,或保存下面的完整代码:

curl -fL https://www.bobobk.com/downloads/rfoptimization/check_rfo_records.py \
    -o check_rfo_records.py
python3 check_rfo_records.py --help
#!/usr/bin/env python3
"""Audit completed RFO cycles; this does not evaluate molecular quality."""
import argparse
from collections import Counter
import json
import math
from pathlib import Path


def audit(records, expected):
    if expected < 1:
        raise ValueError("expected cycle count must be positive")
    if not isinstance(records, list) or not records:
        raise ValueError("records must be a nonempty JSON list")
    if len(records) != expected:
        raise ValueError(f"expected {expected} cycles, found {len(records)}")
    methods = Counter()
    sequences = []
    seconds = 0.0
    for index, row in enumerate(records):
        if not isinstance(row, dict):
            raise ValueError(f"record {index}: expected an object")
        cycle = row.get("cycle")
        if type(cycle) is not int or cycle != index:
            raise ValueError(f"record {index}: expected zero-based cycle {index}")
        method = row.get("method")
        if method not in ("RF3", "Boltz"):
            raise ValueError(f"cycle {index}: unknown method")
        sequence = row.get("mpnn_sequence")
        if not isinstance(sequence, str) or not sequence:
            raise ValueError(f"cycle {index}: missing MPNN sequence")
        if set(sequence) - set("ACDEFGHIKLMNPQRSTVWY"):
            raise ValueError(f"cycle {index}: nonstandard amino acid")
        if sequences and len(sequence) != len(sequences[0]):
            raise ValueError(f"cycle {index}: chain-A length changed")
        elapsed = row.get("wall_time_sec")
        if (type(elapsed) not in (int, float)
                or not math.isfinite(elapsed) or elapsed < 0):
            raise ValueError(f"cycle {index}: invalid wall_time_sec")
        methods[method] += 1
        sequences.append(sequence)
        seconds += elapsed
    return {
        "completed_cycles": len(records),
        "methods": dict(sorted(methods.items())),
        "chain_a_length": len(sequences[0]),
        "unique_handoff_sequences": len(set(sequences)),
        "recorded_cycle_seconds": round(seconds, 2),
        "quality_evaluated": False,
    }


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("records", type=Path)
    parser.add_argument("--expected-cycles", required=True, type=int)
    args = parser.parse_args()
    try:
        records = json.loads(args.records.read_text(encoding="utf-8"))
        result = audit(records, args.expected_cycles)
    except (OSError, UnicodeError, ValueError) as exc:
        parser.exit(1, f"ERROR: {exc}\n")
    print(json.dumps(result, indent=2, allow_nan=False))


if __name__ == "__main__":
    main()

先用这个合成样例试跑。序列和耗时均为演示检查器而编造,不是 RFO 预测结果或性能测量。

python3 - <<'PY'
import json
from pathlib import Path

records = [
    {"cycle": 0, "method": "RF3", "mpnn_sequence": "ACDEFG",
     "wall_time_sec": 12.5},
    {"cycle": 1, "method": "Boltz", "mpnn_sequence": "ACDEYG",
     "wall_time_sec": 20.0},
]
Path("synthetic_records.json").write_text(json.dumps(records))
PY
python3 check_rfo_records.py synthetic_records.json --expected-cycles 2

预期输出:

{
  "completed_cycles": 2,
  "methods": {
    "Boltz": 1,
    "RF3": 1
  },
  "chain_a_length": 6,
  "unique_handoff_sequences": 2,
  "recorded_cycle_seconds": 32.5,
  "quality_evaluated": false
}

检查真实三轮任务时,将脚本保存在 foundry/models/rfo,并从该目录执行:

python3 check_rfo_records.py \
    outputs/tutorial-mixed/example_complex_records.json --expected-cycles 3

非零退出码表示记录没有通过这些检查。检查成功只说明记录满足一致性要求。recorded_cycle_seconds 汇总已保存的完整循环耗时,不包含未形成记录的失败尝试,也不是整个任务的总耗时。脚本统计重复序列但不拒绝它们,因为传入下一轮的序列保持不变也可能是有效结果。

6. 排错与结果评估

现象 处理方式
找不到 MPNN 程序或权重 检查 MPNN_REPO/run.py、MPNN_PYTHON 的绝对路径,以及上游 model_params 目录
RF3 权重被拒绝 将 RF3_CKPT 指向支持置信度预测且包含训练配置的权重
找不到输入文件 从 foundry/models/rfo 运行,或把输入路径改为绝对路径
记录数少于请求轮数 查看失败模型的日志;创建了目录不代表任务完成
有多个 MPNN 样本,下一轮却只有一个输入 单独检查保存的样本;当前程序只传递第一个样本
分数变好,但新序列尚未评估 用实际保存的序列和预定伙伴进行单独重新折叠评估

比较不同任务之前,先确定评估规则。保留初始候选,明确允许从哪些循环选择结果,并对初始设计和优化设计使用相同评估器与输入条件。统计通过率时,不要把失败或缺失评估悄悄移出分母。计算置信度可以用于排序;结合、特异性、稳定性和活性仍需相应测量。

如果研究环肽,还要单独检查实现:cyclic: true 会传给 Boltz,标记 A 链为环状,但此版本的 RF3 优化器没有添加显式成环键约束。循环文档说明了这个限制。上述蛋白复合物试跑不能验证环肽行为。

7. 总结

先检查输入复合物,分别验证两个模型分支,再保留每轮传递的实际序列。用记录检查脚本发现未完成任务,然后独立评估优化后的序列。RFOptimization 提供的是带有可追踪优化过程的候选设计,实验是否成功仍需另行确认。

标签

1024 12306 ablang adsense agents.md ai ai-agent ai-agents ai-seo algorithm amp antibodies automation bioinformatics blockchain boltz bootstrapping boxes c-index cca cdn chatgpt cli cloudflare codex cofoldarena copy cpu监控 csv cuda curl data-leakage data-processing data-quality data-validation datascience datavisualization deployment desktop-app devtools disown docker dovecot download electron esm2 esm3 esmc esmfold2 faceswap fasta fastmcp ffmpeg file-io flashppi flask folium frontend game generator git github-actions google grep hls html http hugo indexnow javascript jev json just k-means kaggle langfuse leecode linux list litellm llm llms.txt logging logs lollipop m3u8 machine-learning macos manacher matplotlib mcp mirror model-evaluation mp3 mp4 mpnn multiomics mutation mysql nanobert nanobodies networkx nginx normalize ollama omegatherm pandas password pep-723 phaser pillow pip postfix preprocessing print protein-design protein-interactions protein-language-models protein-stability protein-structure proxy pydantic pyecharts pyqt python python3 r raincloud reproducibility requests reservoir-sampling rfoptimization rg ripgrep rosettafold3 roundcube rsync s-tui sampling scale scikit-learn scrapy screen seaborn security selenium seo sha256 sklearn solana somaticsignatures spl sqlite ssh standardize static-site subprocess system-one tensorflow tkinter tron tronpy turtle typesafe-ai usdt uv vhhbert vite webp wordcloud wordpress workflow yaml 后台 寓言 概率 经济 贸易 迅雷解析 钱包

友情链接

其它