feat: 实现大规模并行预测功能 (v2.0.0)

新增功能:
- 新增统一批量预测工具 utils/batch_predictor.py
  * 支持单进程/多进程并行模式
  * 灵活的 GPU 配置和显存自动计算
  * 自动临时文件管理和断点续传
  * 完整的 CLI 参数支持(Click 框架)

- 新增 Shell 脚本集合 scripts/
  * run_parallel_predict.sh - 并行预测脚本
  * run_single_predict.sh - 单进程预测脚本
  * merge_results.sh - 结果合并脚本

性能优化:
- 解决 CUDA + multiprocessing fork 死锁问题
  * 使用 spawn 模式替代 fork
  * 文件描述符级别的输出重定向

- 优化预测性能
  * XGBoost OpenMP 多线程(利用所有 CPU 核心)
  * 预加载模型减少重复加载
  * 大批量处理降低函数调用开销
  * 实际加速比:2-3x(12进程 vs 单进程)

- 优化输出显示
  * 抑制模型加载时的权重信息
  * 只显示进度条和关键统计
  * 临时文件自动保存到专门目录

文档更新:
- README.md 新增"大规模并行预测"章节
- README.md 新增"性能优化说明"章节
- 添加详细的使用示例和参数说明
- 更新项目结构和版本信息

技术细节:
- 每个模型实例约占用 2.5GB GPU 显存
- 显存计算公式:建议进程数 = GPU显存(GB) / 2.5
- GPU 瓶颈占比:MolE 表示生成 94%
- 非 GIL 问题:计算密集任务在 C/CUDA 层

Breaking Changes:
- 废弃旧的独立预测脚本,统一使用新工具

相关 Issue: 解决 #并行预测卡死问题
测试平台: Linux, 256 CPU cores, NVIDIA RTX 5090 32GB
This commit is contained in:
2025-10-18 20:53:39 +08:00
parent 4745ce3884
commit a8fea027ac
8 changed files with 1202 additions and 51 deletions

View File

@@ -33,4 +33,68 @@ Enamine库片段预测得分>0.1(因合成性更佳)。
排除含PAINS/Brenk子结构的片段易导致假阳性或代谢不稳定
与已知559个抗生素的Tanimoto相似度<0.5(确保结构新颖性)。
4结果输出
最终获得1,156,945个片段淋病奈瑟菌靶向存储于补充数据或Zenodo仓库中。
最终获得1,156,945个片段淋病奈瑟菌靶向存储于补充数据或Zenodo仓库中。
# 抗菌预测模型输出格式字段解释
## 完整输出字段解释表
### 基础信息
| 字段名 | 数据类型 | 来源 | 计算方法 | 含义说明 |
|--------|--------|------|--------|---------|
| SMILES | 字符串 | 输入数据 | 直接复制 | 分子的 SMILES 结构表示 |
| chem_id | 字符串 | 输入数据 | 直接复制或自动生成 | 化合物的唯一标识符(如 "mol1" |
### 聚合预测结果(每个分子一组值)
| 字段名 | 数据类型 | 来源 | 计算方法 | 含义说明 |
|--------|--------|------|--------|---------|
| apscore_total | 浮点数 | 聚合计算 | log(gmean(所有40个菌株的预测概率)) | 总体抗菌潜力分数:所有菌株预测概率的几何平均数的对数。值越高表示抗菌活性越强,负值表示整体抑制概率较低 |
| apscore_gnegative | 浮点数 | 聚合计算 | log(gmean(革兰阴性菌株的预测概率)) | 革兰阴性菌抗菌潜力分数仅针对革兰阴性菌株23种计算的抗菌分数 |
| apscore_gpositive | 浮点数 | 聚合计算 | log(gmean(革兰阳性菌株的预测概率)) | 革兰阳性菌抗菌潜力分数仅针对革兰阳性菌株17种计算的抗菌分数 |
| ginhib_total | 整数 | 聚合计算 | sum(所有菌株的二值化预测) | 总抑制菌株数:预测被抑制的菌株总数(概率 ≥ 0.04374 的菌株数量),范围 0-40 |
| ginhib_gnegative | 整数 | 聚合计算 | sum(革兰阴性菌株的二值化预测) | 革兰阴性菌抑制数:预测被抑制的革兰阴性菌株数量,范围 0-23 |
| ginhib_gpositive | 整数 | 聚合计算 | sum(革兰阳性菌株的二值化预测) | 革兰阳性菌抑制数:预测被抑制的革兰阳性菌株数量,范围 0-17 |
| broad_spectrum | 整数 (0/1) | 聚合计算 | 1 if ginhib_total >= 10 else 0 | 广谱抗菌标志:如果抑制菌株数 ≥ 10则判定为广谱抗菌药物1否则为 0 |
### 菌株级别预测结果(每个分子 40 行,每行对应一个菌株)
| 字段名 | 数据类型 | 来源 | 计算方法 | 含义说明 |
|--------|--------|------|--------|---------|
| pred_id | 字符串 | 组合生成 | chem_id + ":" + strain_name | 预测组合ID格式为 "化合物ID:菌株名称",如 "mol1:Akkermansia muciniphila (NT5021)" |
| strain_name | 字符串 | 菌株元数据 | 从 40 个菌株列表中提取 | 菌株名称:包含菌株学名和 NT 编号,如 "Akkermansia muciniphila (NT5021)" |
| antimicrobial_predictive_probability | 浮点数 | XGBoost 预测 | model.predict_proba(X)[:, 1] | 抗菌预测概率XGBoost 模型预测该化合物抑制该菌株生长的概率,范围 0-1。这是模型的原始输出概率 |
| no_growth_probability | 浮点数 | XGBoost 预测 | model.predict_proba(X)[:, 0] | 不抑制概率:预测该化合物不抑制该菌株生长的概率,等于 1 - antimicrobial_predictive_probability |
| growth_inhibition | 整数 (0/1) | 阈值二值化 | 1 if antimicrobial_predictive_probability >= 0.04374 else 0 | 生长抑制标签二值化的抑制结果。1 表示预测抑制0 表示预测不抑制。阈值 0.04374 是通过验证集优化得到的 |
| gram_stain | 字符串 | 菌株元数据 | 从 strain_info_SF2.xlsx 中查找 | 革兰染色类型:该菌株的革兰染色分类,值为 "negative"(革兰阴性)或 "positive"(革兰阳性) |
---
## 数据结构说明
### 输出格式特点
- **前 8 列**SMILES 到 broad_spectrum每个分子的聚合结果这些值在该分子的 40 行中保持不变
- **后 6 列**pred_id 到 gram_stain每个分子-菌株对的具体预测,每行对应不同的菌株
### 示例数据
```csv
SMILES,chem_id,apscore_total,apscore_gnegative,apscore_gpositive,ginhib_total,ginhib_gnegative,ginhib_gpositive,broad_spectrum,pred_id,strain_name,antimicrobial_predictive_probability,no_growth_probability,growth_inhibition,gram_stain
CCO,mol1,-9.93,-10.17,-9.74,0,0,0,0,mol1:Akkermansia muciniphila (NT5021),Akkermansia muciniphila (NT5021),0.000102,0.999898,0,negative
CCO,mol1,-9.93,-10.17,-9.74,0,0,0,0,mol1:Bacteroides caccae (NT5050),Bacteroides caccae (NT5050),0.000155,0.999845,0,negative
...(共 40 行,前 8 列相同,后 6 列不同)
```
---
## 关键说明
| 项目 | 说明 |
|------|------|
| 数据量 | 每个输入分子会生成 40 行输出(对应 40 个菌株),因此总行数 = 输入分子数 × 40 |
| 阈值优化 | 默认阈值 0.04374 是通过最大化验证集 F1 分数得到的最优值 |
| 革兰染色分布 | 40 个菌株中23 个为革兰阴性菌17 个为革兰阳性菌 |
| 概率解释 | antimicrobial_predictive_probability 越接近 1表示模型越确信该化合物会抑制该菌株 |
| 应用场景 | 这种格式特别适合强化学习场景,可以直接提取 40 维的预测概率向量作为状态表示 |