鉴权
所有 /api/* 请求都必须带 API Token,放在 Authorization 头里:
Authorization: Bearer <API_TOKEN>
Token 由平台管理员分配,请勿写入前端代码或公开仓库。缺失或错误会返回 401。
本页面本身是公开文档,不含任何凭据;网页版的登录密码与 API Token 是两套独立的认证方式。
快速开始
四步完成一次预测:提交 → 轮询 → 列产物 → 下载。
BASE=https://ai4s.cypherpharma.cloud/api
TOKEN=<API_TOKEN>
# 1) 健康检查
curl -s $BASE/health -H "Authorization: Bearer $TOKEN"
# 2) 提交作业
curl -s -X POST $BASE/jobs \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"model": "boltz",
"input_text": "name: demo\nchains:\n - id: A\n type: protein\n sequence: MQIFVKTLTGKTITLEVEPSDTIENVKAKIQDKEGIPPDQQRLIFAGKQLEDGRTLSDYNIQKESTHRLVLRLRGG\n copies: 1\nmsa: none\nseeds: [42]\nsamples: 1\nrecycles: 3\n",
"params": {"samples": 1}
}'
# → {"job_id":"f534c9a1...","status":"queued",...}
# 3) 轮询状态(queued → running → done)
curl -s $BASE/jobs/<JOB_ID> -H "Authorization: Bearer $TOKEN"
# 4) 列产物并下载
curl -s $BASE/jobs/<JOB_ID>/files -H "Authorization: Bearer $TOKEN"
curl -s -G $BASE/jobs/<JOB_ID>/file \
-H "Authorization: Bearer $TOKEN" \
--data-urlencode 'path=results.json' -o results.json
接口一览
| 方法 | 路径 | 用途 |
|---|---|---|
| GET | /health | 健康检查,返回队列与运行数 |
| GET | /models | 模型清单、显存曲线与默认参数 |
| POST | /jobs | 提交作业 |
| GET | /jobs | 作业列表,支持 ?status=queued&limit=50 |
| GET | /jobs/{id} | 作业详情(含 result_dir、error) |
| POST | /jobs/{id}/cancel | 取消排队或运行中的作业 |
| GET | /jobs/{id}/files | 递归列出产物(相对路径 + 字节数) |
| GET | /jobs/{id}/file?path= | 下载单个产物 |
| GET | /stats | 队列、GPU、各模型峰值显存统计 |
输入格式
预测类 5 个模型(boltz / protenix / chai1 / colabfold / openfold3)统一使用 YAML spec,通过 input_text 内联提交:
name: demo # 作业名,影响产物文件名
chains:
- id: A
type: protein # protein | dna | rna
sequence: MQIFVKTLT... # 单字母序列
copies: 1
- id: B
type: protein
sequence: GSHMK...
ligands:
- id: L
type: ligand
smiles: "CC(=O)O" # 或者 ccd: ATP
copies: 1
msa: none # none | server | cached | /path/to/x.a3m
seeds: [42]
samples: 1
recycles: 3
| 字段 | 说明 |
|---|---|
msa | none 单序列模式(最快,无需联网);server 自动取 MSA(依赖外网);cached 使用缓存;也可写 .a3m 路径 |
copies | 同一条序列的拷贝数 |
ligands | 配体用 smiles 或 CCD 代码 |
seeds / samples / recycles | 随机种子 / 采样数 / recycle 次数 |
Protenix 限制:只支持
msa: none,且 recycles 建议 ≥ 10,否则 pLDDT 会明显偏低。设计类(rfantibody / bindcraft2)不使用上面的 YAML,输入是各自的 JSON 配置,见下文。
7 个模型
| model | 类型 | 输入 | 规模上限 | 说明 |
|---|---|---|---|---|
boltz | 预测 | YAML | 1500 tokens | Boltz-2,通用复合物 |
protenix | 预测 | YAML | 1500 tokens | Protenix 2.0,AF3 风格 |
chai1 | 预测 | YAML | 500 tokens | Chai-1,抗体/复合物 |
colabfold | 预测 | YAML | 2000 tokens | 最省显存,适合长序列 |
openfold3 | 预测 | YAML | 1500 tokens | OpenFold-3 |
rfantibody | 设计 | JSON | — | 三阶段抗体设计 |
bindcraft2 | 设计 | JSON | — | Campaign 式 binder 设计 |
boltz
{"model":"boltz","input_text":"name: ubq\nchains:\n - id: A\n type: protein\n sequence: MQIFVKTLTGKTITLEVEPSDTIENVKAKIQDKEGIPPDQQRLIFAGKQLEDGRTLSDYNIQKESTHRLVLRLRGG\n copies: 1\nmsa: none\nseeds: [42]\nsamples: 1\nrecycles: 3\n"}
protenix
{"model":"protenix","input_text":"name: ubq\nchains:\n - id: A\n type: protein\n sequence: MQIFVKTLTGKTITLEVEPSDTIENVKAKIQDKEGIPPDQQRLIFAGKQLEDGRTLSDYNIQKESTHRLVLRLRGG\n copies: 1\nmsa: none\nseeds: [42]\nsamples: 1\nrecycles: 10\n"}
chai1
{"model":"chai1","input_text":"name: ubq\nchains:\n - id: A\n type: protein\n sequence: MQIFVKTLTGKTITLEVEPSDTIENVKAKIQDKEGIPPDQQRLIFAGKQLEDGRTLSDYNIQKESTHRLVLRLRGG\n copies: 1\nmsa: none\nseeds: [42]\nsamples: 1\nrecycles: 3\n"}
colabfold
{"model":"colabfold","input_text":"name: ubq\nchains:\n - id: A\n type: protein\n sequence: MQIFVKTLTGKTITLEVEPSDTIENVKAKIQDKEGIPPDQQRLIFAGKQLEDGRTLSDYNIQKESTHRLVLRLRGG\n copies: 1\nmsa: none\nseeds: [42]\nsamples: 1\nrecycles: 3\n"}
openfold3
{"model":"openfold3","input_text":"name: ubq\nchains:\n - id: A\n type: protein\n sequence: MQIFVKTLTGKTITLEVEPSDTIENVKAKIQDKEGIPPDQQRLIFAGKQLEDGRTLSDYNIQKESTHRLVLRLRGG\n copies: 1\nmsa: none\nseeds: [42]\nsamples: 1\nrecycles: 3\n"}
rfantibody
三阶段抗体设计。耗时数十分钟起,target_pdb 必须是服务器上已存在的路径(无上传接口)。
{"model":"rfantibody","input_text":"{\"target_pdb\":\"/home/xiaodong/models/targets/flu_HA.pdb\",\"num_designs\":2,\"design_loops\":\"H1:7,H2:6,H3:5-13\",\"hotspots\":\"B146,B170,B177\",\"diffuser_t\":15,\"num_seqs\":1,\"num_recycles\":3}"}
bindcraft2
内置靶点:dynorphin_a、hIL2R、hIL7RA、hPD1、hPDL1、mPDL1。
{"model":"bindcraft2","input_text":"{\"modality\":\"binder\",\"target\":\"hPDL1\",\"campaign_name\":\"pdl1_round1\",\"number_of_final_designs\":1,\"max_trajectories\":2,\"binder_lengths\":[60,80],\"validation_recycles\":3}"}
params 参数
提交时 params 是可选的,会覆盖 spec 里的同名字段:
| 键 | 作用 | 适用范围 |
|---|---|---|
samples | 采样数 | 全部预测类 |
recycles / recycling | recycle 次数 | 全部预测类 |
seeds | [42] 或 "42 43" | 全部预测类 |
steps | 扩散步数 | boltz / protenix |
timeout | 单作业超时秒数,默认 3600 | 全部 |
force | true 时绕过 tokens 上限 | 全部 |
extra | 透传给后端 | 全部 |
提交后返回的 tokens 是折算残基数,est_vram_mb 是预估峰值显存;超过单卡 22000 MB 会直接 422。
结果产物
预测类作业的 result_dir 结构固定:
<job_id>/
├── _spec.yaml 实际执行的 spec
├── results.json 结构化分数与结构文件路径
├── report.html 人工查看用的汇总页
└── work/<cache_key>/ 后端原生输出(.cif / .pdb / .npz)
results.json 里每个采样一项:
{"results":[
{"id":"boltz_s42_m0","seed":42,"sample":0,
"path":".../predictions/demo/demo_model_0.cif",
"plddt":92.08,"ptm":0.910,"iptm":0.0,"ranking":0.919}
]}
path 是服务器绝对路径。下载时用 /jobs/{id}/files 返回的相对路径,或去掉 result_dir 前缀。设计类产物不同:RFantibody 输出 1_rfdiffusion.qv / 2_proteinmpnn.qv / 3_rf2.qv;BindCraft2 输出 3_Ranked/、summary.csv、campaign_metadata.json。
错误码
| 状态码 | 含义 | 处理 |
|---|---|---|
401 | Token 缺失或错误 | 检查 Authorization: Bearer |
404 | 作业或文件不存在 | 确认 job_id 与 path |
422 | 输入不合法 / 超过 tokens 上限 / 预估显存超限 | 缩小规模或修 spec |
429 | 网页版登录尝试过多 | 等待 5 分钟 |
500 | 服务端异常 | 查看作业详情里的 error |
Python 示例
import time, requests
BASE = "https://ai4s.cypherpharma.cloud/api"
HEAD = {"Authorization": "Bearer <API_TOKEN>"}
spec = """name: demo
chains:
- id: A
type: protein
sequence: MQIFVKTLTGKTITLEVEPSDTIENVKAKIQDKEGIPPDQQRLIFAGKQLEDGRTLSDYNIQKESTHRLVLRLRGG
msa: none
seeds: [42]
samples: 1
recycles: 3
"""
job = requests.post(BASE + "/jobs", headers=HEAD,
json={"model": "boltz", "input_text": spec}).json()
jid = job["job_id"]
while True:
info = requests.get(f"{BASE}/jobs/{jid}", headers=HEAD).json()
if info["status"] in ("done", "failed", "cancelled"):
break
time.sleep(5)
if info["status"] == "done":
files = requests.get(f"{BASE}/jobs/{jid}/files", headers=HEAD).json()["files"]
for f in files:
if f["path"].endswith(".cif"):
data = requests.get(f"{BASE}/jobs/{jid}/file", headers=HEAD,
params={"path": f["path"]}).content
open("model.cif", "wb").write(data)
并发与约束
- 2 张 RTX 3090,每卡最多 2 个进程 → 最多 4 个预测作业并行,其余排队。
- 设计类固定预留 12 GB 显存,建议一次只跑一个。
- 预测类
tokens上限:boltz/protenix/openfold3 1500,chai1 500,colabfold 2000。 - 作业结果保留在服务器磁盘上,请及时下载;磁盘余量有限。
- 网页版与 API 共用同一队列,作业按
priority与提交时间排序。