用途
本技能用于搭建和运行 calico 的 Borzoi 变异评分远程工具,按 Borzoi 论文的统计口径对变异进行评分:每个变异的参考与替代 524,288 碱基窗口经 fold-0 网络、反向互补集成、上游 targets 表反变换,从 7,611 条轨道按链求和至 6,385 条,输出 SAD、logSAD、D2、logD2。
技能说明明确指出,该服务不同于端口 8012 上的 run_borzoi_variant_effect(borzoi-pytorch 社区移植,GPU 上输入两条序列返回中心 bin 差值)。需要吞吐量时用后者,需要论文统计量时用本服务。
前提条件
- 从 ToolUniverse 仓库根目录运行,Linux,Python 3.12.3。
- 无需 GPU;aarch64 上也无法使用 GPU(TensorFlow 无对应 aarch64 轮子)。
- 模型环境使用 Python 3.10(技能指定的 python 版本)。
- 需要约 3.9 GiB 权重与基因组文件,加约 1 GiB 环境,目录必须可写。
- 每个请求约 10 GiB 空闲内存(实测峰值 RSS 10,011,120 KB)。
使用方式
- 先运行标准库契约检查,避免提前下载大依赖:
python scripts/remote_validation/setup_skill_preflight.py --implementation borzoi_calico
导出 provider 资源后可加 --check-provider-env;服务器启动后可加 --live,在不运行模型的情况下验证 MCP 工具集。
-
权重目录必须可写:pysam.Fastafile 首次打开基因组时会在旁边生成 hg38.ml.fa.fai;launch.py 会检查
os.access(root, os.W_OK)并拒绝只读挂载。 -
创建环境:
uv venv --seed --managed-python --python 3.10 ~/borzoi-kit-venv
~/borzoi-kit-venv/bin/pip install --no-deps -r \
src/tooluniverse/remote/borzoi_calico/environment/requirements.lock
export TOOLUNIVERSE_BORZOI_CALICO_PYTHON=~/borzoi-kit-venv/bin/python
- 安装两个上游代码库(以归档形式提供,安装时无需克隆):
SETUPTOOLS_SCM_PRETEND_VERSION_FOR_BASKERVILLE=1.0.0 \
~/borzoi-kit-venv/bin/pip install --no-deps -e <baskerville checkout>
SETUPTOOLS_SCM_PRETEND_VERSION_FOR_BORZOI=1.0.1 \
~/borzoi-kit-venv/bin/pip install --no-deps -e <borzoi checkout>
export BORZOI_DIR=<borzoi checkout> BASKERVILLE_DIR=<baskerville checkout>
launch.py 会把 $BORZOI_DIR/src/scripts 加入 worker 的 PYTHONPATH;若 borzoi_sad 无法导入,worker 会拒绝启动。
-
注意 aarch64 上的 TensorFlow 安装问题:技能固定 tensorflow==2.15.1,但该 aarch64 轮子实际不含代码,它通过 Requires-Dist 把实现重定向到 tensorflow-cpu-aws==2.15.1。使用
--no-deps时不会跟随该重定向,因此 lock 中同时加入 tensorflow-cpu-aws==2.15.1。 -
下载并校验权重:
tu remote setup borzoi_calico --only weights
两个文件均在 provider.toml 中声明大小与 sha256,并在 worker 启动前校验:f0/model0_best.h5(744,112,468 字节)、hg38.ml.fa(3,091,663,428 字节)。基因组不是 README 中的 UCSC hg38.fa,而是上游脚本从自有 bucket 获取的 hg38.ml.fa;contig 名必须带 chr 前缀。
- 启动服务并调用:
python -m tooluniverse.remote.borzoi_calico.borzoi_calico_tool
tu doctor --forward http://127.0.0.1:8061/mcp --json
示例参数:{"variants": [{"chrom": "chr1", "pos": 43110773, "ref": "G", "alt": "A"}], "top_tracks": 20}
仅支持 GRCh38、1-based 的 SNV;裸写 "1" 会被规范化为 chr1。
边界与行为
- variants:最多 4 个,超出则被拒绝并给出计数与单变异成本。
- alleles:仅 ACGT 的 SNV,indel 不评分,按名称拒绝。
- pos:整数且 ≥ 1,否则拒绝。
- top_tracks:1–100,超出拒绝;完整 6,385 轨道向量保留在 sad.h5 中。
- 并发:一次一个请求,第二个请求在 worker 锁上排队。
私有分享与调用示例
授权:
tu remote login
tu remote share borzoi_calico
tu remote share borzoi_calico --name my-borzoi-calico-remote --workers 1
密钥缺失、过期或被吊销时,分享会自动启动浏览器流程;显式设置的畸形或已吊销 TOOLUNIVERSE_SERVICE_KEY 会快速失败。tu remote logout 仅移除本地存储的密钥。
本地验证与中继:
tu doctor --forward http://127.0.0.1:8061/mcp --json
tu serve --share --forward http://127.0.0.1:8061/mcp --name validation-borzoi-calico --workers 1
通过本地 MCP 端点调用示例(工具名 run_borzoi_calico_sad):
python - <<'PY'
import asyncio
import json
from fastmcp import Client
async def main():
arguments = json.loads('''{"variants":[{"chrom":"chr1","pos":43110773,"ref":"G","alt":"A"}],"top_tracks":5}''')
async with Client("http://127.0.0.1:8061/mcp") as client:
result = await client.call_tool("run_borzoi_calico_sad", arguments)
print(result)
asyncio.run(main())
PY
预期成功结果包含 implementation、n_variants、n_tracks 为 6385、stats、每个变异 top_tracks 携带四项统计量的 variants 数组,以及 sad_h5。
等价性验证
技能给出通过 kit 入口运行 stock 的命令(bash run.sh sad --mode off ...),并要求逐数据集比较而非按字节比较:HDF5 分配顺序与分块写入器差异可能造成误判。应比较各数据集的名称、形状、dtype 与精确数值:SAD、logSAD、D2、logD2 为 (n, 6385) float16,四张 (6385, 279) 百分位表,以及 snp、chr、pos、ref_allele、alt_allele、percentiles、target_ids、target_labels。
上游细节与限制
技能说明保留两个上游行为:stock 的 sum_length 分支实际为死代码(列表与字符串比较恒为 False),worker 复现而非修正;--shifts 到 baskerville 时已转为列表。
验证状态(2026-10-14):在 NVIDIA GB10 主机(aarch64、20 核、121.6 GiB 统一内存、cc 12.1、驱动 580.173.02)CPU 上、kit 模式关闭下运行;worker 复用 stock 的 initialize_output_h5、write_snp_len、write_pct 与 baskerville 的 snp_seq1、untransform_preds、seqnn 模型,写入相同的 sad.h5。测得与 stock 在三对、全部 16 个数据集上逐字节一致;约 255 秒/变异,最多 4 个变异。公开发布、跨用户隔离、并发、恢复和 indel 均未测试,部署应保持私有。该实现未参与 2026-08-16 的 Platform 矩阵,也未通过 Platform 调用,公开证据仅为单卡本地回环端点。
故障排查
- 干净安装后 import tensorflow 失败:安装 tensorflow-cpu-aws==2.15.1(lock 已包含)。
- worker 报 BORZOI_DIR 或 borzoi_sad.py:检查代码库及 src/scripts 路径。
- worker 报权重目录不可写:pysam 需要写入 .fai。
- “Unable to synchronously create dataset (name already exists)”:把逗号拼接的 --stats 字符串传到了期望列表的辅助函数。
- 请求耗时二十分钟:4 个变异 × 约 255 秒,在 CPU 上运行。