๊ธฐ๋ฅ ์์ธ ๋ณด๊ณ
Silo A โ 3-Arm ๊ฐ์์คํฌ๋ฆฌ๋ (NVIDIA NIM)
SILO A ์ฒญ์ ๊ณ์ด. ๋ณธ ํ์ด์ง์ ๋ชจ๋ ์ฌ์ค ์ฃผ์ฅ์ ์ฝ๋
file:line๋๋ ์ฐ์ถ๋ฌผ ๊ฒฝ๋ก๋ก ์ธ์ฉํ๋ค. ์ ๋ขฐ๋ฑ๊ธ: ์ค์ธก HIGH / surrogate-์๋ MED / surrogate-์ ๋ LOW.
ํต์ฌ ๊ฒฐ๋ก
- ์ค๊ณยท์ฝ๋๋ ์์ฑ, ์คํ ์ฌ๋ก๋ 0๊ฑด. Silo A 3-Arm(์๋ถ์ยทํฉํ์ด๋ยทde novo) 6๊ฐ ๋ชจ๋์ด ๋ชจ๋ ๊ตฌํ๋์ด ๋จ์ํ
์คํธ(mock) 9๊ฑด์ ํต๊ณผํ์ผ๋ [๊ทผ๊ฑฐ: docs/meet_preparation/inspect_evidence/silo_a.md:174], end-to-end ์คํ์ ๋จ ํ ๋ฒ๋ ์๋ค(
outputs/silo_a/๋ฏธ์กด์ฌ) [๊ทผ๊ฑฐ: docs/meet_preparation/inspect_evidence/silo_a.md:171]. - ์คํ ์ฐจ๋จ ์์ธ์ NVIDIA NIM API ํค ๋ถ์ฌ. Arm1ยทArm3๊ฐ ํด๋ผ์ฐ๋ NIM์ ์์กดํ๋ฉฐ, ํ์ฑ ๋ผ์ฐํฐ๋
_has_nim_api_key()=os.getenv("NVIDIA_NIM_API_KEY")๋ก ํค ์ ๋ฌด๋ฅผ ๊ฒ์ดํธํ๋ค [๊ทผ๊ฑฐ: AgenticAI4SCIENCE_pyrosetta_track/repos/ai4sci-kaeri/backend/routers/silo_a.py:65-66]. ํ์ฌ ํ๊ฒฝ์ ํค ๋ฏธ์ค์ [๊ทผ๊ฑฐ: docs/meet_preparation/inspect_evidence/silo_a.md:195]. - NIM 3-arm ์ ์ฒด๋ ๋นํ์ฑ์ด๋, ํ์ฑ ํตํฉ ํ์ดํ๋ผ์ธ์ ๋ก์ปฌ de novo ๊ฒฝ๋ก(
_run_silo_a)๋ฅผ ์ค์ ํธ์ถํ๋ค. NIM ์์กด 3-arm(์๋ถ์ยทํฉํ์ด๋ยทde novo)์ ๋ฐฑ์ ยท์คํ ์ํ์ด์ง๋ง,pipeline_local/orchestrator.py:_run_silo_a()๋ Arm3์ ํด๋นํ๋ RFdiffusion+ProteinMPNN์ NIM ์์ด ๋ก์ปฌ GPU๋ก ๊ฐ๋ํ๋ค [๊ทผ๊ฑฐ: pipeline_local/orchestrator.py:1395-1454, 843-853]. ์ค์ ๋ฐ๊ตด ์ฑ๊ณผ๋ ๋๋ถ๋ถ Silo B(PyRosetta) ๊ฒฝ๋ก ์ฐ๋ฌผ โ "NIM 3-arm ๋ฏธ์คํ / ๋ก์ปฌ de novo ๋ถ๋ถ ๊ฐ๋" ์ผ๋ก ์ ์ง ํ๊ธฐ.
1. ์์น: "์ค๊ณ"๊ฐ ์๋๋ผ "๊ตฌํ๋จ, ๋ฏธ์คํ"
์ฃผ์ฅ โ ๊ทผ๊ฑฐ โ ํจ์
- ์ฃผ์ฅ: Silo A๋ ์ค๊ณ๋ง ์๋ ๊ฒ์ด ์๋๋ผ ์ค์ ์ฝ๋๊น์ง ์กด์ฌํ๋ค. ๋ค๋ง ์ด๋ค ์์น์์๋ end-to-end๋ก ๋์๊ฐ ์ ์ ์๋ค.
- ๊ทผ๊ฑฐ:
- ์ค๊ณ ๋ฌธ์:
docs/SYSTEM_ARCHITECTURE.md(3-arm ๊ตฌ์กฐ ASCII ๋์) [๊ทผ๊ฑฐ: docs/SYSTEM_ARCHITECTURE.md:25, 34-46] - ์ค์ ์ฝ๋(๋ฐฑ์
, ๋นํ์ฑ):
_backup/orphaned_20260609/pipelines/silo_a/src/6๊ฐ ๋ชจ๋ [๊ทผ๊ฑฐ: _backup/orphaned_20260609/pipelines/silo_a/README.md:17-26] - ํ์ฑ HTTP API(์คํ
):
backend/routers/silo_a.pyโ Phase 1 dry-run๋ง ๋ ธ์ถ [๊ทผ๊ฑฐ: AgenticAI4SCIENCE_pyrosetta_track/repos/ai4sci-kaeri/backend/routers/silo_a.py:1-7] - ํจ์: "Silo A = ๋ฏธ๊ตฌํ"์ ์ฌ์ค์ด ์๋๋ค. ์ ํํ ์ํ๋ "์ฝ๋ ์์ฑ ยท ์คํ 0๊ฑด ยท API ์คํ ". PI ๋ณด๊ณ ์ "์ค๊ณ ๋จ๊ณ"๋ก ๋ญ๋ฑ๊ทธ๋ฆฌ์ง ์๊ณ ๊ตฌํ ์์ค์ ๋ถ๋ฆฌ ํ๊ธฐํด์ผ ์ ์งํ๋ค.
1.1 ์์น ๋งต โ 4๊ณณ์ ๋ถ์ฐ
| ๊ณ์ธต | ๊ฒฝ๋ก | ์ํ | ๊ทผ๊ฑฐ |
|---|---|---|---|
| ์ค๊ณ ๋ฌธ์ | docs/SYSTEM_ARCHITECTURE.md |
โ ์์ฑ (์๋ ๊ตฌ์กฐ) | docs/SYSTEM_ARCHITECTURE.md:24-30 |
| ํต์ฌ ์ฝ๋ | _backup/orphaned_20260609/pipelines/silo_a/src/ (6 ๋ชจ๋) |
โ ๊ตฌํ, ๋นํ์ฑ ๋ฐฑ์ | _backup/orphaned_20260609/pipelines/silo_a/README.md:17-26 |
| NIM ํด๋ผ์ด์ธํธ | _backup/orphaned_20260609/bionemo/ (5 ํด๋ผ์ด์ธํธ) |
โ ๊ตฌํ, ๋นํ์ฑ ๋ฐฑ์ | EV08 ยง2.C |
| ํ์ฑ API | โฆ/ai4sci-kaeri/backend/routers/silo_a.py |
๐ก Phase 1 dry-run ์คํ | backend/routers/silo_a.py:119-128 |
| ํ์ฑ ๋ก์ปฌ ๋์ | pipeline_local/orchestrator.py:_run_silo_a() |
๐ก ๊ฐ๋ ๊ฐ๋ฅ โ Arm3์ ํด๋นํ๋ RFdiffusion+ProteinMPNN๋ง ๋ก์ปฌ ์คํ, Arm1ยทArm2ยทESMFold ๋ฏธํฌํจ (ยง8) | pipeline_local/orchestrator.py:1395-1454 |
[๋ฐ์ดํฐ: _workspace/report_site2/_evidence/EV08_silo_a_trace.md ยง2] โ ์ ๋งต์ EV08 ์ถ์ ๊ฒฐ๊ณผ๋ฅผ ์์ฝํ ๊ฒ.
2. 3-Arm ์ํคํ ์ฒ ๋์
SSTR2 pocket PDB + ์๋๋ถ์/wildtype"] subgraph A1["Arm 1 ยท ์๋ถ์"] m1["MolMIM ์์ฑ
(NIM)"] --> m2["QED ํํฐ"] --> m3["DiffDock ๋ํน
(NIM)"] end subgraph A2["Arm 2 ยท ํฉํ์ด๋"] p1["๋ณ์ด์ฒด 11์ข
(Ala scan + ๋ณด์กด์นํ)"] --> p2["FlexPepDock
(PyRosetta, ์กฐ๊ฑด๋ถ)"] end subgraph A3["Arm 3 ยท de novo"] d1["RFdiffusion
๋ฐฑ๋ณธ์ค๊ณ (NIM)"] --> d2["ProteinMPNN
์์ด์ค๊ณ (NIM)"] --> d3["ESMFold
pLDDTโฅ70 (NIM)"] end seed --> A1 & A2 & A3 A1 & A2 & A3 --> us["UnifiedScorer
์ ๊ทํยท๊ฐ์คํฉ์ฐ"] us --> rank["์์ ํ๋ณด
(โ outputs/silo_a ๊ณํ, ๋ฏธ์คํ)"] end classDef blue fill:#e3f0fb,stroke:#1a6fbf,color:#0b3d66; class SA,A1,A2,A3 blue;
๋์ ์ถ์ฒ: ์ฝ๋ ๊ตฌ์กฐ(
arms.py3 Runner +scoring.pyUnifiedScorer) [๊ทผ๊ฑฐ: _backup/orphaned_20260609/pipelines/silo_a/src/arms.py:24-284, scoring.py:9-76].rank โ outputs/silo_a๋ ๊ณํ ๋จ๊ณ(๋ฏธ์คํ) [๊ทผ๊ฑฐ: docs/meet_preparation/inspect_evidence/silo_a.md:171].
3. Arm๋ณ ๊ตฌํ ์์ธ (์ฝ๋ ํ๋ฆ: ๋ชฉ์ โ ์ ๋ ฅ โ ์ฐ์ฐ โ ์ถ๋ ฅ)
๊ฐ Arm์ ์ถ์ ๋ฒ ์ด์ค ArmRunner.run(config, clients)๋ฅผ ๊ตฌํํ๋ฉฐ, ์ง์
์ cfg.enabled๊ฐ False๋ฉด ์ฆ์ RunStatus.SKIPPED๋ฅผ ๋ฐํํ๊ณ , ์์ธ๋ errors ๋ฆฌ์คํธ์ ๋์ ํด SUCCESS/PARTIAL๋ก ์ํ๋ฅผ ๋ถ๊ธฐํ๋ค [๊ทผ๊ฑฐ: _backup/orphaned_20260609/pipelines/silo_a/src/arms.py:13-21, 35-40, 90-97].
Arm 1 โ ์๋ถ์ (MolMIM ์์ฑ โ QED ์ ๋ ฌ โ DiffDock ๋ํน)
- ๋ชฉ์ : ๊ธฐ์กด SSTR2 ๋ฆฌ๊ฐ๋ SMILES๋ฅผ ์๋๋ก ์ฝ๋ฌผ์ ์ฌ ์ ๊ท ์๋ถ์๋ฅผ ์์ฑํ๊ณ , ํฌ์ผ์ ๋ํนํด ๊ฒฐํฉ ์ ๋ขฐ๋๋ฅผ ๋งค๊ธด๋ค. ์ค์ธก HIGH(์ฝ๋ ์กด์ฌ)
- ์
๋ ฅ: config์
arm1.seed_molecules(์ด๋ฆยทSMILES ์), ์์ฑ ํ๋ผ๋ฏธํฐ(molmim_num_molecules=10,molmim_algorithm="CMA-ES",molmim_property="QED",molmim_min_similarity=0.3), ๊ทธ๋ฆฌ๊ณ ๋ํน ํ๊นpocket.complex_pdb[๊ทผ๊ฑฐ: config.py:36-46]. - ํ๋ฆ:
1. ๊ฐ ์๋๋ง๋ค
clients.molmim.generate(...)๋ก ๋ถ์ ์ง๋จ์ ๋ฐ๊ณ , ์๋ต dict์์sample(SMILES)๊ณผscore(QED)๋ฅผ ์ถ์ถํดCandidateRecord๋ก ์ ์ฌ [๊ทผ๊ฑฐ: arms.py:42-61]. 2. ์ ์ฒด ํ๋ณด๋ฅผqed๋ด๋ฆผ์ฐจ์ ์ ๋ ฌ ํ ์์top_k_for_docking(๊ธฐ๋ณธ 15)๋ง ๋ํน ๋์์ผ๋ก ์ ๋ณ [๊ทผ๊ฑฐ: arms.py:65-66, config.py:43]. 3. ์ ๋ณ๋ ๊ฐ ํ๋ณด๋ฅผclients.diffdock.dock_smiles(protein_pdb_path, smiles, num_poses=5)๋ก ๋ํนํ๊ณ ์๋ต์confidence๋ฅผ ํผ์ฒ์ ๋ณํฉ [๊ทผ๊ฑฐ: arms.py:71-81, config.py:44]. ๋ํน ์์ธ ์ ํด๋น ํ๋ณด๋dock_confidence=0, dock_success=0์ผ๋ก ํด๋ฐฑ ์ ์ฌ [๊ทผ๊ฑฐ: arms.py:82-88]. - ์ถ๋ ฅ:
dock_confidence/dock_success๊ฐ ์ฑ์์งCandidateRecord๋ฆฌ์คํธ + ์ง๊ณ ํผ์ฒ(total_generated,total_docked)๋ฅผ ๋ด์ArmResult[๊ทผ๊ฑฐ: arms.py:90-97]. - ํจ์: ๊ณจ๊ฒฉ์ ์๋น๋์ผ๋
molmim.generateยทdiffdock.dock_smiles๋ชจ๋ NIM ํด๋ผ์ฐ๋ ํธ์ถ์ด๋ผ ํค ๋ถ์ฌ ์ ์ ๋ ์์ธ ํด๋ฐฑ โ ์ฌ์ค์ ๋ฏธ๊ฐ๋. 1์ฐจ ํ๊น์ด ํฉํ์ด๋(SST-14)๋ผ ์ฐ์ ์์๊ฐ ๋ฎ์๋ ๊ฒ์ผ๋ก ๋ณด์ โ [๋ฏธ๊ฒ์ฆ: ์ฐ์ ์์ ๊ฒฐ์ ๊ทผ๊ฑฐ ๋ฌธ์ ์์].
Arm 2 โ ํฉํ์ด๋ (๋ณ์ด์ฒด โ ๋ณ์ด ์ถ์ถ โ FlexPepDock, ์กฐ๊ฑด๋ถ)
- ๋ชฉ์ : wildtype ๋๋น ๋ณ์ด์ฒด ํฉํ์ด๋์ ๊ฒฐํฉ ์๋์ง๋ฅผ PyRosetta ๋ํน์ผ๋ก ํ๊ฐํ๋ค. PyRosetta๊ฐ ์์ผ๋ฉด ๋ณ์ด ๊ฐ์๋ง ๊ธฐ๋กํ๋ ์กฐ๊ฑด๋ถ ๊ตฌํ. ์กฐ๊ฑด๋ถ
- ์
๋ ฅ:
arm2.wildtype์์ด,arm2.variants(์ด๋ฆยท์์ด), ๊ฒ์ดํธ ํ๋๊ทธuse_pyrosetta(๊ธฐ๋ณธ True)ยทcomplex_pdbยทrelax_after_dock[๊ทผ๊ฑฐ: config.py:49-60]. - ํ๋ฆ:
1.
use_pyrosetta=True์ด๊ณcomplex_pdb๊ฐ ์ง์ ๋ ๊ฒฝ์ฐ์๋งpipelines.silo_b.src.docking.PyRosettaDockingRunner๋ฅผ importํด ๋ํน ๋ฌ๋๋ฅผ ์ด๊ธฐํ. import ์คํจ ์ ๊ฒฝ๊ณ ๋ง ๋จ๊ธฐ๊ณ ์์ด ๋ถ์ ๋ชจ๋๋ก ๊ฐ๋ฑ,complex_pdb๋ฏธ์ค์ ์ ๋ํน ๋นํ์ฑ ๊ฒฝ๊ณ [๊ทผ๊ฑฐ: arms.py:121-144]. 2. ๊ฐ ๋ณ์ด์ฒด์ ๋ํด wildtype๊ณผ ๊ธธ์ด๋ฅผ ๊ฒ์ฆ(๋ถ์ผ์น ์ error ์ ์ฌ ํ skip)ํ๊ณ , ์์น๋ณ ์ฐจ์ด๋ฅผ{wt}{i+1}{mt}ํ์ ๋ณ์ด ๋ฌธ์์ด๋ก ์ถ์ถ [๊ทผ๊ฑฐ: arms.py:146-160]. 3. ๋ํน ๋ฌ๋๊ฐ ์์ผ๋ฉดdock_candidate(...)๋ก ฮG(delta_energy)ยท์ฑ๊ณต ์ฌ๋ถ๋ฅผ ์ฐ์ถํ๊ณ , ์ฑ๊ณต+relax_after_dock์ด๋ฉดPyRosettaComplexRelaxer.relax(...)๋ก ฮG๋ฅผ ๊ฐฑ์ ํ๋ฉฐ clash/interface/RMSD๋ฅผ ์ถ๊ฐ. ๋ํน ๋ฌ๋๊ฐ ์์ผ๋ฉดdock_success=0๋ง ๊ธฐ๋ก [๊ทผ๊ฑฐ: arms.py:162-184]. - ์ถ๋ ฅ: ๋ณ์ด ๊ฐ์์(๊ฐ๋ฅ ์) ๋ํน/relax ํผ์ฒ๋ฅผ ๋ด์
CandidateRecord๋ฆฌ์คํธ์ArmResult[๊ทผ๊ฑฐ: arms.py:185-197]. - ํจ์: Arm2๋ Silo B(PyRosetta ๋ณ์ด+๋ํน)์ ๋์ผ ์์์ ์์กดํ๋ฏ๋ก(์ฝ๋์์ผ๋ก๋
silo_b.src.docking์ ์ง์ import), ์ค์ ๋ฐ๊ตด์ Silo B๊ฐ ์ ๋ดํ๊ณ Arm2๋ Silo A ๋ด๋ถ์์ ์ค๋ณตยท๋ฏธ๊ฐ๋ ์ํ๊ฐ ๋จ.
Arm 3 โ de novo (RFdiffusion ๋ฐฑ๋ณธ โ ProteinMPNN ์์ด โ ESMFold pLDDT)
- ๋ชฉ์ : ํฌ์ผ์ ํ๊น์ผ๋ก ๋ฐฑ๋ณธ์ ๋์์ธํ๊ณ (RFdiffusion) ๊ทธ ์์ ์์ด์ ์ ํ(ProteinMPNN) ์ ํ ์ ๋ขฐ๋(ESMFold pLDDT)๋ก ๊ฑฐ๋ฅด๋ ์ ๊ท ๋ฐ์ธ๋ 3๋จ ์ค๊ณ. ์ค์ธก HIGH(์ฝ๋ ์กด์ฌ)
- ์
๋ ฅ:
pocket.complex_pdb,arm3.num_designs(๊ธฐ๋ณธ 5),seqs_per_backbone(4),diffusion_steps(50),plddt_threshold(70.0), ๊ทธ๋ฆฌ๊ณconfig.seed[๊ทผ๊ฑฐ: config.py:63-70]. - ํ๋ฆ:
1.
num_designsํclients.rfdiffusion.design_binder(pdb_path, contigs="B1-369/0 10-30", hotspot_res=[], diffusion_steps, random_seed=seed+i)๋ฅผ ํธ์ถํด ๋ฐฑ๋ณธ PDB๋ฅผ ์์ง [๊ทผ๊ฑฐ: arms.py:217-231]. 2. ๊ฐ ๋ฐฑ๋ณธ์clients.proteinmpnn.predict(input_pdb, num_seq_per_target, sampling_temp=0.2)๋ก ์์ด์ ๋์์ธํ๊ณ , ์๋ต์ด FASTA ๋ฌธ์์ด์ด๋ฉดparse_fasta๋ก, ๋ฆฌ์คํธ๋ฉด ๊ทธ๋๋ก ํ์ฑ [๊ทผ๊ฑฐ: arms.py:233-252]. 3. ๊ฐ ์์ด์clients.esmfold.predict(seq)๋ก ์ ๊ณmean_plddt(๋ฆฌ์คํธ๋ฉด ํ๊ท )๋ฅผ ๊ณ์ฐ,plddt >= plddt_threshold(70.0)์ธ ์์ด๋งCandidateRecord๋ก ์ฑํ [๊ทผ๊ฑฐ: arms.py:254-272, config.py:67]. - ์ถ๋ ฅ: pLDDTโฅ70 ์์ด์
CandidateRecord+ ์ง๊ณ ํผ์ฒ(backbones,designed_seqs)๋ฅผ ๋ด์ArmResult[๊ทผ๊ฑฐ: arms.py:276-283]. - ํจ์: ๊ฐ์ฅ ์ผ์ฌ์ฐฌ ๊ฒฝ๋ก์ด๋ 3๊ฐ NIM(RFdiffusion/ProteinMPNN/ESMFold)์ด ๋ชจ๋ ํ์ โ NIM ํค ์์ด๋ ๊ฐ๋ ๋ถ๊ฐ. ๋จ, ๊ฐ์ RFdiffusion+ProteinMPNN ์กฐํฉ์ด ํ์ฑ ๋ ํฌ์ ๋ก์ปฌ ๊ฒฝ๋ก(
pipeline_local)์์๋ NIM ์์ด ์ค์ ๋ก ๊ฐ๋๋๋ค(ยง8 ์ฐธ์กฐ).
4. ์ค์ผ์คํธ๋ ์ด์ โ Arm ์์ฐจ ์คํ โ ํตํฉ ๋ญํน โ UnifiedCandidate ๋ณํ
- ๋ชฉ์ : 3๊ฐ Arm์ ์์๋๋ก ๋๋ ค ํ๋ณด๋ฅผ ๋ชจ์ผ๊ณ , ๋จ์ผ ์ ์๋ก ํตํฉ ๋ญํนํ ๋ค, ์ฌ์ผ๋ก ๊ฐ ๋น๊ต์ฉ ํ์คํ(
UnifiedCandidate)์ผ๋ก ํ์ฐํ๋ค. ์ค์ธก HIGH(์ฝ๋ ์กด์ฌ) - ์
๋ ฅ: config ๊ฒฝ๋ก +
NimClientBundle(์ฃผ์ ํ ํด๋ผ์ด์ธํธ ๋ฌถ์) [๊ทผ๊ฑฐ: _backup/orphaned_20260609/pipelines/silo_a/src/orchestrator.py:30-41]. - ํ๋ฆ:
1.
_build_arms()๊ฐ[Arm1, Arm2, Arm3]๋ฅผ ์์ฑํ๊ณexecute()๊ฐ ๊ฐ Arm์ ์์ฐจ ์คํ โ Arm์ด ์์ธ๋ฅผ ๋์ ธ๋RunStatus.FAILED๋ก ๊ฐ์ธ ๋ค์ Arm์ผ๋ก ์งํ(๋ถ๋ถ ์คํจ ๊ฒฉ๋ฆฌ) [๊ทผ๊ฑฐ: orchestrator.py:43-68]. 2. ๋ชจ๋ Arm ํ๋ณด๋ฅผ ํฉ์ณUnifiedScorer.rank_candidates(...)๋ก ์ ์ยท์์ ๋ถ์ฌ [๊ทผ๊ฑฐ: orchestrator.py:70]. 3. Arm๋ณ ์ํยทํ๋ณด์ยท์๋ฌ์๋ฅผ ์์ฝํ manifest๋ฅผ JSON์ผ๋ก ๊ธฐ๋กํ๊ณPipelineResult๋ฐํ [๊ทผ๊ฑฐ: orchestrator.py:72-97]. 4.to_unified()๊ฐ ArmโModality ๋งคํ๊ณผ ํจ๊ป ํผ์ฒ๋ฅผ bridge ์งํ(dg_est,clash,stability,feasibility)๋ก ํ์ฐํดUnifiedCandidate๋ฆฌ์คํธ ์์ฑ [๊ทผ๊ฑฐ: orchestrator.py:99-144]. - ์ถ๋ ฅ:
run_manifest.json+ ๋ญํน๋ ํ๋ณด + ์ฌ์ผ๋ก ํตํฉ์ฉUnifiedCandidate๋ฆฌ์คํธ. - ํจ์: ๋ถ๋ถ ์คํจ๋ฅผ ๊ฒฉ๋ฆฌํ๋ ๊ตฌ์กฐ๋ผ ์ผ๋ถ Arm๋ง ๊ฐ๋๋ผ๋ ํ์ดํ๋ผ์ธ์ด ์์ฃผํ๋๋ก ์ค๊ณ๋จ. ๋จ ยง6๋๋ก end-to-end ์คํ ์์ฒด๊ฐ 0๊ฑด์ด๋ผ manifest ์ฐ์ถ๋ฌผ์ ๋ฏธ์กด์ฌ.
5. UnifiedScorer โ ์ด์ง Arm ์ ์ ํตํฉ (์ ๊ทํ โ ๊ฐ์คํฉ์ฐ โ ์ ๋ ฌ)
- ๋ชฉ์ : 3๊ฐ Arm์ ์๋ก ๋ค๋ฅธ ํผ์ฒ(QED, dock_confidence, ฮE, pLDDT)๋ฅผ ๊ณตํต 0โ1 ์ฒ๋๋ก ์ ๊ทํยท๊ฐ์คํฉ์ฐํด Arm ๊ฐ ์ง์ ๋น๊ต๊ฐ ๊ฐ๋ฅํ ๋จ์ผ ์ ์๋ฅผ ์ฐ์ถํ๊ณ ์์๋ฅผ ๋งค๊ธด๋ค. ์ค์ธก HIGH(์ฝ๋ ์กด์ฌ)
- ์
๋ ฅ:
ScoringConfig.weights(qed 0.15ยทdock_confidence 0.35ยทdelta_energy 0.25ยทplddt 0.15ยทdiversity 0.10) + ๊ฐ ํ๋ณด์featuresdict [๊ทผ๊ฑฐ: _backup/orphaned_20260609/pipelines/silo_a/src/config.py:73-80]. - ํ๋ฆ:
1.
score_candidate(features, arm)๊ฐ Arm ์ข ๋ฅ์ ๋ฐ๋ผ ํด๋น ํผ์ฒ๋งnormalize(value, lo, hi)๋ก minmax ์ ๊ทํ ํ ๊ฐ์ค์น๋ฅผ ๊ณฑํดarm_score/arm_max๋ฅผ ๋์ [๊ทผ๊ฑฐ: scoring.py:21-36]. 2.arm_max>0์ด๋ฉดarm_score/arm_max๋ก 0โ1 ์ฌ์ ๊ทํ(clamp) [๊ทผ๊ฑฐ: scoring.py:38-44]. 3. ๋ค์์ฑ ํญ๊ณผ ๊ฒฐํฉ:score = (1 โ w.diversity)ยทnormalized_arm + w.diversityยทdiversityํ 0โ1 clamp + 4์๋ฆฌ ๋ฐ์ฌ๋ฆผ [๊ทผ๊ฑฐ: scoring.py:46-49]. 4.rank_candidates(...)๊ฐ ์ ํ๋ณด์ ์ ์๋ฅผ ๋ถ์ฌํ๊ณ ๋ด๋ฆผ์ฐจ์ ์ ๋ ฌํด 1๋ถํฐrank๋ฅผ ์ฑ์ ์CandidateRecord๋ก ์ฌ์์ฑ [๊ทผ๊ฑฐ: scoring.py:51-76]. - ์ถ๋ ฅ:
scoreยทrank๊ฐ ์ฑ์์ง ์ ๋ ฌ๋CandidateRecord๋ฆฌ์คํธ.
| Arm | ํผ์ฒ | ์ ๊ทํ ๋ฒ์ | ๊ฐ์ค์น ๋ณ์ | ๊ทผ๊ฑฐ line |
|---|---|---|---|---|
| Arm1 SmallMol | qed | 0โ1 | w.qed (0.15) |
scoring.py:27 |
| Arm1 SmallMol | dock_confidence | 0โ1 | w.dock_confidence (0.35) |
scoring.py:28 |
| Arm2 FlexPep | โdelta_energy | 0โ50 | w.delta_energy (0.25) |
scoring.py:31-32 |
| Arm3 DeNovo | plddt | 0โ100 | w.plddt (0.15) |
scoring.py:35 |
| ๊ณตํต | diversity | 0โ1 | w.diversity (0.10) |
scoring.py:46-47 |
- ํจ์: Arm ๊ฐ ์ง์ ๋น๊ต๊ฐ ๊ฐ๋ฅํ ๊ณตํต ์ฒ๋๋ฅผ ์ค๊ณํ ์ ์ ๊ฐ์ . ๋จ, ๋ชจ๋ ์ ์๋ ์๋ ์์์ฉ surrogate โ ์ ๋ ์นํ๋/ํ์ฑ์ ์๋ฏธํ์ง ์์ surrogate-์๋ MED.
โ ๏ธ ์๋ ค์ง ๊ฒฐํจ:
diversity๊ฐ์ค์น(scoring.py:46-47)๊ฐ ํฉ์ฐ์ ๋ค์ด๊ฐ๋, ์ด๋ค Arm๋diversityํผ์ฒ๋ฅผ ์ฐ์ถํ์ง ์์ โfeatures.get("diversity", 0.0)์ด ํญ์ 0์ผ๋ก ๊ท๊ฒฐ, ์ฆ ๋ค์์ฑ ํญ์ด ์ ์์ ๊ธฐ์ฌํ์ง ์๊ณ ์ต๋ ์ ์๋ฅผ 0.9๋ก ๊น๋ ํจ๊ณผ๋ง ๋จ์ [๋ฏธ๊ฒ์ฆ: ์๋ ๋ฏธ๊ตฌํ์ธ์ง ์ฌํ ์ถ๊ฐ ๊ณํ์ธ์ง ๋ถ๋ช ] [๊ทผ๊ฑฐ: scoring.py:47, docs/meet_preparation/inspect_evidence/silo_a.md:156-165, EV08 ยง4].
6. NVIDIA NIM ์์กด์ฑ โ ์คํ ์ฐจ๋จ์ ํต์ฌ
์ฃผ์ฅ โ ๊ทผ๊ฑฐ โ ํจ์
- ์ฃผ์ฅ: Arm1ยทArm3๋ NVIDIA NIM ํด๋ผ์ฐ๋ API์ ์ง์ ์์กดํ๋ฉฐ, ์ด๊ฒ์ด Silo A ๋ฏธ์คํ์ ๊ทผ๋ณธ ์์ธ์ด๋ค.
- ๊ทผ๊ฑฐ:
- 5๊ฐ NIM ํด๋ผ์ด์ธํธ๊ฐ
bionemo/์ ๊ตฌํ๋จ (MolMIM, DiffDock, ProteinMPNN, ESMFold, RFdiffusion 5๊ฐ*_client.pyํ์ผ ๋ชจ๋ ์ค์ฌ ํ์ธ) [๊ทผ๊ฑฐ: _backup/orphaned_20260609/bionemo/{molmim,diffdock,proteinmpnn,esmfold,rfdiffusion}_client.py] - ์๋ํฌ์ธํธ ์: MolMIM
https://health.api.nvidia.com/v1/biology/nvidia/molmim, DiffDockโฆ/mit/diffdock[๊ทผ๊ฑฐ: EV08 ยง2.C] - ํ์ฑ API์ dry-run ๊ฒ์ดํธ โ
_has_nim_api_key()=os.getenv("NVIDIA_NIM_API_KEY")[๊ทผ๊ฑฐ: backend/routers/silo_a.py:65-66], ํค ์์ผ๋ฉด dry-run ๊ฐ์ [๊ทผ๊ฑฐ: backend/routers/silo_a.py:69-70] - ํ์ฌ ํ๊ฒฝ ํค ๋ฏธ์ค์ [๊ทผ๊ฑฐ: docs/meet_preparation/inspect_evidence/silo_a.md:195]
- ํจ์: Silo A ์คํ = ์ธ๋ถ ํด๋ผ์ฐ๋ ์๊ฒฉ์ฆ๋ช ํ๋ณด๊ฐ ์ ํ์กฐ๊ฑด. ์จํ๋ ๋ฏธ์ค(KAERI) ์ด์ ์ ์ฑ ์ ํด๋ผ์ฐ๋ ์์กด์ด ๋ถ๋ด์ด์๋ ๊ฒ์ผ๋ก ๋ณด์ด๋ฉฐ, ์ค์ ํ์ฑ ํ์ดํ๋ผ์ธ์ NIM์ ์ ๊ฑฐํ๊ณ ๋ก์ปฌ ๊ฒฝ๋ก๋ก ์ ํ๋จ(ยง8).
7. ํ์ฑ HTTP API โ Phase 1 ์คํ (๋ชฉ์ โ ์ ๋ ฅ โ ์ฐ์ฐ โ ์ถ๋ ฅ)
- ๋ชฉ์ : ํ์ฑ ๋ ํฌ์ Silo A FastAPI ๋ผ์ฐํฐ๋ ์ค์ ์ถ๋ก ์์ด dry-run ์ก ์๋ฝ๊ณผ ํ๊ฒฝ ํฌ์ค ํ๋ก๋ธ๋ง ๋ ธ์ถํ๋ค. ์ค์ ๋ชจ๋ธ ํธ์ถ์ Phase 2 ์์ปค๋ก ์ ๋ณด. ์คํ
- ์
๋ ฅ:
SiloARunRequest(sequencesยทuse_nimยทarms) [๊ทผ๊ฑฐ: AgenticAI4SCIENCE_pyrosetta_track/repos/ai4sci-kaeri/backend/routers/silo_a.py:25-28]. - ํ๋ฆ:
- ํค๋ ์ฃผ์์ด ์๋๋ฅผ ๋ช ์: "Phase 1 intentionally exposes dry-run orchestration and health probes onlyโฆReal ProteinMPNN, RFdiffusion, ESMFold, and DiffPepBuilder calls are reserved for the Phase 2 worker integration." [๊ทผ๊ฑฐ: backend/routers/silo_a.py:1-7]
POST /run์_nim_dry_run_enabled(use_nim)(=use_nim and not _has_nim_api_key())๋ก dry-run ์ฌ๋ถ๋ฅผ ํ์ ํ๊ณ , ์job_id(uuid4)์ "inference is deferred to Phase 2" ๋ฉ์์ง๋ง ๋ฐํ โ ์ค์ ์ถ๋ก ํธ์ถ ์์ [๊ทผ๊ฑฐ: backend/routers/silo_a.py:69-70, 119-129].GET /status/{job_id}ยทGET /results/{job_id}๋ ๋น stub ์๋ต [๊ทผ๊ฑฐ: backend/routers/silo_a.py:132-150].GET /health๋_has_nim_api_key()์_discover_conda_env_names()(conda env list --jsonsubprocess)๋ก NIM ํค ์ ๋ฌดยทํ์ conda env 4์ข (proteinmpnn/rfdiffusion/esmfold/diffpepbuilder) ๊ฐ์ฉ์ฑ์ ์ ๊ฒํด ๋ณด๊ณ [๊ทผ๊ฑฐ: backend/routers/silo_a.py:22, 73-116, 153-168].- ์ถ๋ ฅ: dry-run ํ์ ยทjob_idยทํฌ์ค ์ํ ๋ฑ ๋ฉํ๋ฐ์ดํฐ JSON (๋ชจ๋ธ ์ฐ์ถ๋ฌผ ์์).
- ํจ์: API ๊ณ์ฝ(์คํค๋งยท๋ผ์ฐํธ)์ ์ ์๋์ผ๋ ์์ปค ํตํฉ(Phase 2)์ ๋ฏธ๊ตฌํ. PI ๊ด์ ์์ "API๊ฐ ์๋ค โ ์ถ๋ก ์ด ๋๋ค"๋ฅผ ๋ถ๋ช ํ ๊ตฌ๋ถํด์ผ ํจ.
8. ํ์ฑ ๋ก์ปฌ ๊ฒฝ๋ก โ pipeline_local._run_silo_a() (NIM ์์ด ์ค์ ๊ฐ๋)
์ค์ ์ ์ : Silo A๊ฐ 100% ๋นํ์ฑ์ธ ๊ฒ์ ์๋๋ค. ํ์ฑ ํตํฉ ํ์ดํ๋ผ์ธ(
pipeline_local)์ NIM์ ์ ๊ฑฐํ ๋ก์ปฌ de novo ๊ฒฝ๋ก๋ฅผ ์ค์ ๋ก ํธ์ถํ๋ค. (Arm1 ์๋ถ์ยทArm2 ํฉํ์ด๋๋ ๋ฏธํฌํจ, Arm3์ ํด๋นํ๋ ๋ฐฑ๋ณธ+์์ด ์ค๊ณ๋ง)
- ๋ชฉ์ : ๋์ผ ์ฌ์ผ๋ก ๋ฃจํ์์ Silo A ๋ชซ์ผ๋ก RFdiffusion ๋ฐฑ๋ณธ ์ค๊ณ + ProteinMPNN ์์ด ์ค๊ณ๋ฅผ ๋ก์ปฌ GPU๋ก ์คํํด ์์ด ํ๋ณด๋ฅผ ๊ณต๊ธํ๋ค. ์ค์ธก HIGH(์ฝ๋ ์กด์ฌ)
- ์
๋ ฅ:
step01_out(receptor_pdb_path, pocket_residues),iteration, ๊ทธ๋ฆฌ๊ณconfig["dual_silo"]["silo_a"](gpu_device ๊ธฐ๋ณธ 2, ์ ํ์ n_backboneยทk_seq_per_backbone) [๊ทผ๊ฑฐ: pipeline_local/orchestrator.py:1395-1426]. - ํ๋ฆ:
1. dual ์ ์ฉ ํ๋ผ๋ฏธํฐ๋ก config๋ฅผ ๋ฎ์ด์ฐ๊ณ
device="cuda:{gpu_device}"์ค์ [๊ทผ๊ฑฐ: pipeline_local/orchestrator.py:1414-1426]. 2.step02_backbone.generate_backbones(receptor_pdb, pocket_info, config)์คํ โ ๋ฐฑ๋ณธ PDB๊ฐ ์์ผ๋ฉด ๊ฒฝ๊ณ ํ ๋น ๋ฆฌ์คํธ ๋ฐํ(Silo B๋ง์ผ๋ก ์งํ) [๊ทผ๊ฑฐ: pipeline_local/orchestrator.py:1428-1438]. 3.step03_sequence.design_sequences(backbones, config)๋ก ์์ด ์ค๊ณ, ์คํจ ์ ๋น ๋ฆฌ์คํธ ๋ฐํ [๊ทผ๊ฑฐ: pipeline_local/orchestrator.py:1441-1450]. 4. ํธ์ถ๋ถ์์ ๋ก๊ทธ"Silo A (RFdiffusion + ProteinMPNN) ์คํ ์ค..."ํ ๊ฒฐ๊ณผ๋ฅผ ๋์ผ ๋ถ๊ธฐ๋ก ์ ๋ฌ [๊ทผ๊ฑฐ: pipeline_local/orchestrator.py:843-853]. - ์ถ๋ ฅ:
SequenceEntry๋ฆฌ์คํธ(์คํจ ์ ๋น ๋ฆฌ์คํธ). ์ดํ ํ๋ณด์๋source="silo_a"ํ๊ทธ๊ฐ ๋ถ์ฌ๋์ด Silo B ์ฐ๋ฌผ๊ณผ ๊ตฌ๋ถยทํตํฉ๋๋ค [๊ทผ๊ฑฐ: pipeline_local/orchestrator.py:983-990, 1217-1228]. - ํจ์: ๋ฐฑ์ ์ NIM 3-arm๊ณผ ๋ฌ๋ฆฌ, ํ์ฑ ๋ก์ปฌ ๊ฒฝ๋ก๋ Arm3 ๊ณจ๊ฒฉ(RFdiffusion+ProteinMPNN)๋ง ๋ก์ปฌ๋ก ์ด์ํ๋ฉฐ ESMFoldยทMolMIMยทDiffDockยทFlexPep์ ๋น ์ ธ ์๋ค. ์ฆ "Silo A ์ ๋ ๋ฏธ์คํ"์ด ์๋๋ผ "NIM 3-arm ๋ฏธ์คํ / ๋ก์ปฌ de novo ๋ถ๋ถ ๊ฐ๋ ๊ฐ๋ฅ"์ผ๋ก ์ ์ง ํ๊ธฐํด์ผ ํ๋ค.
9. ์ ์ง ํ๊ธฐ: ์๋ ๊ตฌ์กฐ vs. ์ค์ ํ์ฑ ์ฝ๋ (P5 ๊ดด๋ฆฌ)
์ฃผ์ฅ โ ๊ทผ๊ฑฐ โ ํจ์
- ์ฃผ์ฅ:
docs/SYSTEM_ARCHITECTURE.md๊ฐ ๊ธฐ์ ํ Silo A/B ๋ถ๋ฆฌ ๊ตฌ์กฐ๋ ํ์ฌ ํ์ฑ ์ฝ๋๋ฒ ์ด์ค์ ์กด์ฌํ์ง ์๋๋ค. - ๊ทผ๊ฑฐ:
- ์๋: ์ต์์
pipelines/silo_a/ยทpipelines/silo_b/[๊ทผ๊ฑฐ: docs/SYSTEM_ARCHITECTURE.md:24-30] - ์ค์ : ์ต์์
pipelines/๋ถ์ฌ, ํ์ฑ ์ฝ๋๋ ๋ ๋ฆฝ ๋ ํฌโฆ/ai4sci-kaeri/์pyrosetta_flow/+AG_src/pipeline/๋จ์ผ ํตํฉ [๊ทผ๊ฑฐ: EV14 ยง1, docs/SYSTEM_ARCHITECTURE.md vs ์ค์ ls ๊ฒฐ๊ณผ] - NIM ํด๋ผ์ด์ธํธ๋ ํ์ฑ ๋ ํฌ์ ๋ถ์ฌ(๋ฐฑ์ ์๋ง ์กด์ฌ), runner๋ "ESMFold ํ์ โ OFF" ๋ฑ NIM ๋นํ์ฑ ๋ช ์ [๊ทผ๊ฑฐ: EV14 ยง3]
- ํจ์: Silo A๋ ์ด๊ธฐ ์ํคํ ์ฒ(ํด๋ผ์ฐ๋ NIM 3-arm)์ ์ ์ฐ์ผ๋ก, ์จํ๋ ๋ฏธ์ค PyRosetta ํตํฉ ํ์ดํ๋ผ์ธ์ผ๋ก ์งํํ๋ฉฐ ๋นํ์ฑ ๋ณด์กด๋จ. ๋ณธ ๋ณด๊ณ ๋ ์ค์ ์ฝ๋ ์์น ๊ธฐ์ค์ผ๋ก ์์ฑํ๊ณ ์ด ๊ดด๋ฆฌ๋ฅผ ๋ช ์ํ๋ค(์์น P5).
(ํตํฉยทNIM OFF)"] r2["AG_src/pipeline"] r3["pipeline_local _run_silo_a
(RFdiff+MPNN ๋ก์ปฌ, Arm3๋ง)"] end subgraph BAK["๋ฐฑ์ (๋นํ์ฑ)"] b1["_backup/.../silo_a (๊ตฌํ๋จ)"] b2["_backup/.../bionemo (NIM ํด๋ผ)"] end ia -.์งํ/๋นํ์ฑํ.-> b1 ia -.๋ก์ปฌ ๋ถ๋ถ ๊ณ์น.-> r3 ib -.ํตํฉ.-> r1 classDef blue fill:#e3f0fb,stroke:#1a6fbf,color:#0b3d66; classDef gray fill:#f0f0f0,stroke:#999,color:#555; class INTENT,ia,ib gray; class REAL,r1,r2,r3 blue; class BAK,b1,b2 gray;
๋์ ์ถ์ฒ [๊ทผ๊ฑฐ: _workspace/report_site2/_evidence/EV14_arch_gap.md ยง1, ยง3].
10. ์ข ํฉ ์ํํ (์ ์ง ๋ฑ๊ธ)
| ๋จ๊ณ | ์ํ | ์ ๋ขฐ๋ฑ๊ธ | ๊ทผ๊ฑฐ |
|---|---|---|---|
| ์ํคํ ์ฒ ์ค๊ณ | โ ์๋ฃ | HIGH | docs/SYSTEM_ARCHITECTURE.md (์ ์ฒด) |
| NIM 3-arm ์ฝ๋ ๊ตฌํ(6 ๋ชจ๋) | โ ์๋ฃ(๋ฐฑ์ ) | HIGH | _backup/.../silo_a/README.md:17-26 |
| ๋จ์ ํ ์คํธ(mock) | โ 9๊ฑด ํต๊ณผ | HIGH | inspect_evidence/silo_a.md:174 |
| ํตํฉ ํ ์คํธ | โ ๋ฏธ์์ฑ | โ | inspect_evidence/silo_a.md:175 |
| HTTP API | ๐ก Phase 1 dry-run ์คํ | โ | backend/routers/silo_a.py:1-7 |
| NIM 3-arm End-to-End ์คํ | โ 0๊ฑด (outputs/silo_a ๋ฏธ์กด์ฌ) | โ | inspect_evidence/silo_a.md:171 |
| NIM API ํค | โ ๋ฏธ์ค์ | โ | inspect_evidence/silo_a.md:195 |
| ํ์ฑ ๋ก์ปฌ de novo ๊ฒฝ๋ก | ๐ก _run_silo_a() ๊ฐ๋ ๊ฐ๋ฅ(Arm3๋ง, NIM ์์ด) |
MED | pipeline_local/orchestrator.py:1395-1454 |
์ดํ: Silo A = NIM 3-arm ์ค๊ณ+๊ตฌํ ์๋ฃ / NIM ๊ฒฝ๋ก ์คํ 0๊ฑด / ํ์ฑ ๋ก์ปฌ de novo(Arm3) ๋ถ๋ถ ๊ฐ๋ ๊ฐ๋ฅ. ์ค์ ๋ฐ๊ตด ์ฑ๊ณผ๋ ๋๋ถ๋ถ Silo B ๊ฒฝ๋ก ์ฐ๋ฌผ์ด๋ฉฐ, NIM 3-arm ์ ์ฒด๋ ํด๋ผ์ฐ๋ ํค ์ฌ๋์ ๋๋ ์์ปค(Phase 2) ํตํฉ ์ ์ฌํ์ฑ ๊ฐ๋ฅํ ์์ฐ.
์ฉ์ด
- NIM (NVIDIA Inference Microservice): NVIDIA๊ฐ ํธ์คํ ํ๋ ์๋ฌผํ ๋ชจ๋ธ ์ถ๋ก ํด๋ผ์ฐ๋ API (MolMIMยทDiffDockยทRFdiffusionยทProteinMPNNยทESMFold).
- QED: Quantitative Estimate of Drug-likeness (์ฝ๋ฌผ์ ์ฌ์ฑ 0โ1).
- pLDDT: ESMFold ๊ตฌ์กฐ ์์ธก ์ ๋ขฐ๋ (0โ100, 70 ์ด์ ์ฑํ).
- FlexPepDock: PyRosetta ๊ธฐ๋ฐ ์ ์ฐ ํฉํ์ด๋ ๋ํน ํ๋กํ ์ฝ.
- dry-run: ์ค์ ์ถ๋ก ์์ด ์ค์ผ์คํธ๋ ์ด์ ๊ฒฝ๋ก๋ง ๊ฒ์ฆํ๋ ๋ชจ์ ์คํ.