Language
Tool
Stack
Database
.
โโโ data # AI ๋ชจ๋ธํ์ต์ ์ํ ๋ฐ์ดํฐ ์
โ โโโ df_merged.csv # ๋ณํฉ๋ ๋
ธ๋ ๋ฐ์ดํฐ์
(unknown ๋ผ๋ฒจ ํฌํจ)
โ โโโ elliptic_data_v2.pt # PyTorch Geometric์ฉ ์ ์ฒด ๊ทธ๋ํ ๋ฐ์ดํฐ ๊ฐ์ฒด ํ์ผ
โ โโโ elliptic_node_final.csv # ์ต์ข
์ ์ฒ๋ฆฌ๋ ๋
ธ๋ ํผ์ฒ ๋ฐ์ดํฐ์
โ
โโโ model_train # AI ๋ชจ๋ธํ์ต ๊ณผ์
โ โโโ train_gnn+pge_explainer.ipynb # GNN GAT + Explainer ๋ชจ๋ธ ํ์ต ํ์ผ
โ
โโโ models # ํ์ต๋ ๋ชจ๋ธ ์ ์ฅ์
โ โโโ saved
โ โโโ elliptic_gat_best.pt # ์ต์ ์ ์ฑ๋ฅ์ ๋ธ GNN GAT ํ์ต ๋ชจ๋ธ ํ์ผ
โ โโโ explainer_pg.pt # GNN ์์ธก ๊ฒฐ๊ณผ ํด์์ ์ํ Explainer ๋ชจ๋ธ ํ์ผ
โ
โโโ .env # ํ๊ฒฝ ๋ณ์ ์ค์ ํ์ผ (Neo4j ์ ์ ์ ๋ณด, OpenAI API Key ๋ฑ)
โโโ .gitignore # Git ๋ฒ์ ๊ด๋ฆฌ ์ ์ธ ํ์ผ ๋ชฉ๋ก
โโโ api_server.py # FastAPI ๊ธฐ๋ฐ AI ๋ชจ๋ธ ์๋น ์๋ฒ ์ฝ๋
โโโ final.py # ๋ฐ์ดํฐ ๋ก๋, ๋ชจ๋ธ ์ถ๋ก , ๊ฒฐ๊ณผ ๋ถ์ ๋ฑ ์ ์ฒด ๋ถ์ ๋ก์ง ์คํ ์ฝ๋
โโโ README.md # ํ๋ก์ ํธ ์ค๋ช
๋ฌธ์
โโโ requirements.txt # ํ์ํ ํ์ด์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ฐ ๋ฒ์ ๋ชฉ๋ก
Elliptic ๋ฐ์ดํฐ์
์ ์คํ
์ด๋ธ ์ฝ์ธ ๊ฑฐ๋ ๋ฐ์ดํฐ๋ฅผ ํฌํจํ๊ณ elliptic_txs_features.csv, elliptic_txs_classes.csv, elliptic_txs_edgelist.csv 3๊ฐ์ ํ์ผ๋ก ๊ตฌ์ฑ๋์ด ์์ต๋๋ค. ๋
ธ๋์ ์ฃ์ง ๊ธฐ๋ฐ์ผ๋ก ๋ถ๋ฅ๋์ด ์์ด Neo4j ์ง์๊ทธ๋ํ ๊ตฌ์ถ์ ์ ํฉํ ํํ์
๋๋ค.
โ ๊ฑฐ๋ ๊ด๊ณ๋ (elliptic_txs_edgelist.csv)
- ํ: 203,769๊ฐ ์ด: 2๊ฐ
- ๊ฑฐ๋ ๊ด๊ณ ์ฆ, ์๊ธ ์ด๋ ๊ฒฝ๋ก๋ฅผ ๋ํ๋ด๋ ๋ฐ์ดํฐ
- A์ง๊ฐ์์ B์ง๊ฐ์ผ๋ก ์ฝ์ธ์ด ์ด๋ํ๋ค๋ฉด, ์ด๋ '๊ฑฐ๋(Transaction)'๋ผ๋ ๋ ธ๋ ๊ฐ์ ์ฐ๊ฒฐ๋ก ํํ๋จ
| txId1 (์ถ๋ฐ ๋ ธ๋) | txId2 (๋์ฐฉ ๋ ธ๋) |
|---|---|
| 230425980 | 5530458 |
โก ๊ฑฐ๋ ์์ฑ ์ ๋ณด (elliptic_txs_features.csv)
- ํ: 203,769๊ฐ ํธ๋์ญ์ (๋ ธ๋) ์ด: 167๊ฐ
- ๊ฐ ๊ฑฐ๋(๋ ธ๋)๊ฐ ๊ฐ์ง๋ 166์ฐจ์์ ๊ณ ์ ํ ํน์ง ๋ฒกํฐ๋ก ํด๋น ๊ฑฐ๋ ์์ฒด์ ํน์ฑ(Local Features)์ ์ด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ ์ง๊ณ ์ ๋ณด(Aggregated Features)๋ก ์ด๋ฃจ์ด์ง
- ํด๋น ๋ฐ์ดํฐ์ ์์๋ ๊ฐ์ธ์ ๋ณด๋ณด์์ ์ํด features์ ํน์ง์ด ์ต๋ช ํ๋์ด ์์
1. Local Features (93๊ฐ)
- ํด๋น ๊ฑฐ๋ ์์ฒด์ ์ ๋ณด
- (์: ํ์์คํฌํ ์ธ ์์๋ฃ, ์
/์ถ๊ธ ํ์, ๊ฑฐ๋๋ ๋ฑ ์ ๋ณด ์ต๋ช
ํ )
2. Aggregated Features (73๊ฐ)
- ํด๋น ๊ฑฐ๋์ ์ฐ๊ฒฐ๋ ์ด์ ๋
ธ๋๋ค์ ๊ฑฐ๋ ๊ธฐ๋ฐ ํต๊ณ ์ ๋ณด
- (์: ์ด์ ๊ฑฐ๋๋ค์ ํ๊ท ๊ฑฐ๋๋, ์ด์์ ์ด์์ด ๊ฐ์ง ํ์คํธ์ฐจ ๋ฑ)
โข ์ ๋ต ๋ ์ด๋ธ (elliptic_txs_classes.csv)
- ํ: 203,769๊ฐ ์ด: 2๊ฐ
- ๊ฑฐ๋ ์ ์(0)/๋น์ ์(1)/๋ฏธ๋ถ๋ฅ(-1)๋ฅผ ๋ํ๋ด๋ ๋ฐ์ดํฐ, ๋ถ๊ท ํ ๋ฐ์ดํฐ์ ํน์ง
- ๋ฐ์ดํฐ ๋ถํฌ
- ๋ถ๋ฒ (illicit) - ์ฝ 4,545๊ฐ (2%)
- ํฉ๋ฒ (licit) - ์ฝ 42,019๊ฐ (21%)
- unknown = ๋ฏธ๋ถ๋ฅ - ์ฝ 157,205๊ฐ (77%)
- 0 (Licit): ๊ฑฐ๋์, ์ง๊ฐ ์๋น์ค ๋ฑ ํฉ๋ฒ์ ๊ฑฐ๋ (์ ์)
- 1 (Illicit): ๋คํฌ์น, ๋์ฌ์จ์ด, ์๊ธ์ธํ ๋ฑ ๋ถ๋ฒ ๊ฑฐ๋ (๋น์ ์)
- Unknown: ์์ง ๋ถ๋ฅ๋์ง ์์ ๊ฑฐ๋ (์ ์ฒด์ ์ฝ 98% ์ฐจ์ง, ์ค์ง๋ ํ์ต ํ์ฉ ๊ฐ๋ฅ)
GNN๋ชจ๋ธ ํ์ต ๋จ๊ณ์์๋ GAT ๋ชจ๋ธ ๋์ ์ด๊ธฐ์ ๋ฐ์ดํฐ ์ ๊ทํ ๋ถ์ฌ์ ํด๋์ค ๋ถ๊ท ํ์ผ๋ก ์ธํ Gradient Explosion(NaN ๋ฐ์) ๋ฐ ๋ฎ์ F1-Score(0.04) ๋ฌธ์ ์ ์ง๋ฉดํ์ต๋๋ค. ์ดํ GCN ๋ณ๊ฒฝ๊ณผ Weighted Loss, BatchNorm ๋ฑ์ ๋์ ํ์ฌ ํ์ต ์์ ์ฑ๊ณผ Recall์ ๊ฐ์ ํ์ผ๋, ๋ชจ๋ธ์ด ๊ทธ๋ํ ๊ตฌ์กฐ(Edge)๋ณด๋ค ๋ ธ๋ ์์ฒด ํผ์ฒ์ ๊ณผ๋ํ๊ฒ ์์กดํ์ฌ ๋จ์ ์ง๋ํ์ต๊ณผ ๋ค๋ฅผ ๋ฐ ์๋ ๊ฒฐ๊ณผ(์ ํ๋ 0.9799)๋ฅผ ๋ณด์์ต๋๋ค. ์ด์ EdgeForcedGATNet์ ์ต์ข ๊ณ ์ํ์ฌ Input Feature์ Edge์ ๊ณผ๊ฐํ Dropout์ ์ ์ฉํ์ฌ ๋ ธ๋ ํผ์ฒ ์์กด๋๋ฅผ ๋ฎ์ถ๊ณ ์ด์ ์ ๋ณด ํ์ต์ ๊ฐ์ ํ์ต๋๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก ๋จ์ ์ ํ๋๋ ์กฐ์ ๋์์ผ๋(0.8878), ์ฃ์ง ์ ๋ณด ํ์ฉ์ด ๊ฒ์ฆ๋ ๊ฒฌ๊ณ ํ ๊ทธ๋ํ ํ์ต ๋ชจ๋ธ์ ๊ตฌ์ถํ ์ ์์์ต๋๋ค.
XAI ๋ชจ๋ธ์ 'Feature Dominance' ๋ฌธ์ ์ ํด๊ฒฐ๊ณผ์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ํ์ต๋ ๋ชจ๋ธ์ ์ค๋ช ํ๊ธฐ ์ํด ์ด๊ธฐ์ GNN๋ชจ๋ธ์ ๊ฑฐ๋ ๊ด๊ณ์ ์ค์ํ Node์ ๋ณด๋ฅผ ์ค์๋ ์์ผ๋ก ์ถ๋ ฅํ๋ GNNExplainer๋ฅผ ํ์ต์์ผฐ์ผ๋, ์ค์๊ฐ ๊ธ์ต ์ฌ๊ธฐ ํ์ง ์์คํ ์ ํน์ฑ์ Low Latency(๋ฎ์์ง์ฐ์๊ฐ)๊ฐ ํ์์ ์ด๋ผ ํ๋จํ์ฌ Inductive ๋ฐฉ์์ PGExplainer๋ก ๊ณ ๋ํํ์์ต๋๋ค. ์ด๋ฅผ ํตํด ์ค๋ช ์์ฑ ์๊ฐ์ ์ ์ด(sec) ๋จ์์์ 0.0X์ด(ms) ๋จ์๋ก ๋จ์ถํ์ต๋๋ค. PGExplainer ํ์ต ๊ณผ์ ์์ ๋ชจ๋ ์ฃ์ง์ ์ค์๋(Mask)๊ฐ 0.0000์ผ๋ก ์๋ ดํ๋ ํ์ ๋ฐ์์ ํด๊ฒฐํ๊ธฐ ์ํด Learning Rate๋ฅผ 0.003์์์ 0.0005 ์์ค์ผ๋ก ๋ฎ์ถฐ ์์ ์ฑ์ ํ๋ณดํ๊ณ , ๊ท์ ๊ณ์๋ฅผ ์ํํ์ฌ ๋ก๊ทธ ์ฐ์ฐ์ ์ํฅ๋ ฅ์ ์ค์ฌ ๊ฐ์ ํ์์ต๋๋ค. ๋ง์ง๋ง์ผ๋ก ๋ฐ์ดํฐ ์ ์์ ์ต๋ค์๋ฅผ ์ฐจ์งํ๋ ๋ฏธ๋ถ๋ฅ ๊ฑฐ๋์ ์ํฅ๋ ฅ์ผ๋ก NaN๊ฐ ์ ํ๋๋ ํ์์ ๋ฐฉ์งํ๊ธฐ ์ํด NaN ๋ฐ์ ์ ํด๋น ๋ฐฐ์น๋ ๋ฌด์ํ์ฌ Loop ๋ด์์ total_loss๊ฐ ์ค์ผ๋์ง ์๋๋ก ํ์ตํ์ต๋๋ค.
[ํ์ต ํ๊ฒฝ]
- GPU : NVIDIA A100-SXM4-40GB(Google Colab ํ๊ฒฝ)
- Framework : PyTorch 2.9.0, PyTorch Geometric
- ๋ฐ์ดํฐ ๋ถํ : Train 60% / Val 20% / Test 20%
GNN ๋ชจ๋ธ&PGExplainer๋ฅผ ํตํด ํน์ ๊ฑฐ๋ํจํด์ ๋น์ ์์ ์ธ ์์ง์์ ์ฃผ๋ณ ๋ ธ๋์ ๋ณด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ ๋ฌ๋ฐ์ ํ, Neo4j ์ง์๊ทธ๋ํ๋ฅผ ๊ตฌ์ถํ๊ณ RAG LLM ๊ธฐ๋ฐ ์ค๋ช ์ ํตํด AI๊ฐ ๋ค์๊ณผ ๊ฐ์ ์ถ๋ก ์ ์ถ๋ ฅํ๋ ์์คํ ์ ๊ตฌ์ถํ์์ต๋๋ค.
ID 99201 ๊ฑฐ๋๋ ์์ฒด ์์ฑ(๊ธ์ก, ์๊ฐ)์ ์ ์์ด์ง๋ง, 2๋จ๊ณ ๊ฑด๋ํธ(2-hop)์ ์๋ ๋ ธ๋๋ค์ด ์ต๊ทผ ๋ถ๋ฒ ์๊ธ(Class 1)๊ณผ ๋ค์ ์ฐ๊ฒฐ๋์ด ์์ผ๋ฏ๋ก, ์ด ๊ฑฐ๋ ๋ํ '์๊ธ ์ธํ์ ์ค๊ฐ ๊ฒฝ๋ก'์ผ ํ๋ฅ ์ด 85%์ด๋ค
๋จผ์ , ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ ๋จ๊ณ์์๋ Elliptic ๋ฐ์ดํฐ์ ์ ํผ์ฒ(feature)์ ํด๋์ค(class) ํ์ผ์ ๋ณํฉํ๊ณ , ๋ถ์์ ๋ถํ์ํ 'unknown' ํด๋์ค ๋ฐ์ดํฐ๋ฅผ ์ ๊ฑฐํ์ฌ ์ ํ๋๋ฅผ ๋์์ต๋๋ค. ๋ํ, ์ง์ ๊ทธ๋ํ ๋ด์์ ์ฃ์ง(Edge)์ ์์ฑ์ ํ๋ถํ๊ฒ ๋ง๋ค๊ธฐ ์ํด, ๊ธฐ์กด ์ฃ์ง ๋ฆฌ์คํธ์ ์กด์ฌํ์ง ์๋ '๊ฑฐ๋ ๊ธ์ก(amount)'๊ณผ '์๊ฐ(time)' ์ ๋ณด๋ฅผ ๋๋ค์ผ๋ก ์์ฑํ์ฌ ์ถ๊ฐํจ์ผ๋ก์จ, ์ต์ข ์ ์ผ๋ก ์ฝ 4๋ง 6์ฒ ๊ฐ์ ๋ ธ๋์ 3๋ง 6์ฒ ๊ฐ์ ์ฃ์ง๋ก ๊ตฌ์ฑ๋ ์ ์ ๋ ๋ฐ์ดํฐ์ ์ ๋ง๋ จํ์์ต๋๋ค.
์ด์ด์ง๋ ์ถ๊ฐ ๋ณ์ ๋งคํ ๋จ๊ณ์์๋ ํฅํ ์ฐ๋๋ ๊ฑฐ๋์ธ์ด๋ชจ๋ธ(LLM)์ด ๊ทธ๋ํ์ ๋งฅ๋ฝ์ ๋ ์ ์ดํดํ ์ ์๋๋ก ๋ ธ๋ ์ ๋ณด๋ฅผ ๊ฐํํ์์ต๋๋ค. ๋ถ๋ฒ ๊ฑฐ๋(Class 1)๋ก ์๋ณ๋ ๋ ธ๋์๋ 'Hacker', 'Ransomware', 'Lazarus Group'๊ณผ ๊ฐ์ ๊ตฌ์ฒด์ ์ธ entity_type๊ณผ commet๋ฅผ ๋ถ์ฌํ๊ณ , ํฉ๋ฒ ๊ฑฐ๋(Class 2)์๋ 'Normal User' ์ ๋ณด๋ฅผ ๋งคํํ์ฌ ๋ฐ์ดํฐ์ ์๋ฏธ๋ก ์ ๊ฐ์น๋ฅผ ๋์์ต๋๋ค.
์ค๋น๋ ๋ฐ์ดํฐ๋ Neo4j ์ง์๊ทธ๋ํ ๊ตฌ์ถ ๋จ๊ณ๋ฅผ ํตํด ์ค์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ก ์ด๊ด๋์์ต๋๋ค. ๋ ธ๋์ ์ฃ์ง ์ ์ฌ ํจ์๋ฅผ ๊ฐ๊ฐ ๊ตฌํํ์ฌ ์ ์ ๋ ๋ฐ์ดํฐํ๋ ์์ Neo4j Aura DB์ ์ ์ฌํจ์ผ๋ก์จ, ๊ฑฐ๋ ๊ด๊ณ๋ฅผ ์๊ฐํํ๊ณ ์ง์ํ ์ ์๋ ํ๊ฒฝ์ ์กฐ์ฑํ์์ต๋๋ค.
๋ง์ง๋ง์ผ๋ก ์กฐํ ๋ก์ง ๊ตฌ์ถ ๋จ๊ณ์์๋ ํน์ ์ง๊ฐ ์ฃผ์๋ฅผ ์ ๋ ฅ๋ฐ์ ์ฐ๊ด๋ ๊ฑฐ๋ ์ฆ๊ฑฐ๋ฅผ ์ถ์ถํ๋ ํ์ดํ๋ผ์ธ์ ์์ฑํ์์ต๋๋ค. ์ฌ์ฉ์๊ฐ ๋จ์ผ ๋๋ ๋ค์์ ์ง๊ฐ ์ฃผ์๋ฅผ ์ ๋ ฅํ๋ฉด, ์์คํ ์ ์๋์ผ๋ก Cypher ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ์ฌ ํด๋น ์ง๊ฐ๊ณผ 1์ด ๊ด๊ณ์ ์๋ ๋ ธ๋ ๋ฐ ์ฃ์ง ์ ๋ณด๋ฅผ ์๋ธ๊ทธ๋ํ(Evidence Graph) ํํ๋ก ์กฐํํฉ๋๋ค. ์ด ๊ฒฐ๊ณผ๋ ์ต์ข ์ ์ผ๋ก JSON ํ์์ผ๋ก ์ถ๋ ฅ๋์ด, LLM์ด ๋ต๋ณ์ ์์ฑํ๋๋ฐ ๊ตฌ์ฒด์ ์ธ ์ฆ๊ฑฐ ๋ฐ์ดํฐ๋ก ํ์ฉ๋ ์ ์๋๋ก ๊ตฌํ๋์์ต๋๋ค.
์ด ๋จ๊ณ๋ ๋ญ์ฒด์ธ์ด ์์ ๊ตฌ์ถ๋ GNN GAT ๋ชจ๋ธ์ ๊ฒฐ๊ณผ๊ฐ๊ณผ Neo4j ์กฐํ ํ์ดํ๋ผ์ธ์์ ์ถ๋ ฅ๋ 1์ด ์๋ธ๊ทธ๋ํ๋ฅผ ์ฐธ์กฐํด RAG ๊ธฐ๋ฐ ๊ฒ์์ผ๋ก LLM ์์ฐ์ด ๋ต๋ณ ์์ฑ์ ๊ตฌํํฉ๋๋ค.
์ด ๋จ๊ณ์์๋ ๋ญ์ฒด์ธ ํ๋ ์์ํฌ์ GPT-4o ๋ชจ๋ธ์ ํ์ฉํฉ๋๋ค. ์์คํ ์ '๋ธ๋ก์ฒด์ธ AML ๋ถ์ ์ ๋ฌธ๊ฐ' ํ๋ฅด์๋๋ก ์ค์ ํ๊ณ , ์์ ์ ๋ฌ๋ฐ์ ์๋ธ๊ทธ๋ํ(Evidence Graph)์ ์ํ ์ ์(risk score)๋ฅผ ํ๋กฌํํธ์ ์ฃผ์ ํฉ๋๋ค. ์ด๋, Pydantic ํ์๋ฅผ ์ ์ฉํ์ฌ LLM์ ๋ต๋ณ์ด ๋จ์ ํ ์คํธ๊ฐ ์๋ '์์ธ ์ค๋ช ', '์์ฝ(20์ ์ดํ)', 'ํต์ฌ ๋ถ๋ ํฌ์ธํธ(3๊ฐ)'์ ์ ํด์ง JSON ๊ท๊ฒฉ์ ์๊ฒฉํ ๋ฐ๋ฅด๋๋ก ์ ์ดํฉ๋๋ค.
๋ง์ง๋ง์ผ๋ก ์ ์ฒด ํ์ดํ๋ผ์ธ ํตํฉ ๋จ๊ณ์์๋ run_pipeline ํจ์๋ฅผ ํตํด ์ด ๋ชจ๋ ๊ณผ์ ์ ํ๋๋ก ๋ฌถ์ต๋๋ค. [GNN, PGExplainer ํ์ง โ Neo4j ์กฐํ โ LLM ๋ถ์]์ ํ๋ฆ์ด ํ ๋ฒ์ ์คํ์ผ๋ก ์ด๋ฃจ์ด์ง๋ฉฐ, ์ต์ข ์ ์ผ๋ก ์ฌ์ฉ์๋ ์๊ฐํ ๊ฐ๋ฅํ ๊ทธ๋ํ ๋ฐ์ดํฐ์ ํจ๊ป, ํด๋น ๊ฑฐ๋๊ฐ ์ ์ํํ์ง ์ค๋ช ํ๋ ์์ฐ์ด ์ค๋ช ์ ๋์์ ๋ฐ์๋ณผ ์ ์๊ฒ ๋ฉ๋๋ค.
[๋ฐฐํฌ ํ๊ฒฝ]
- Dockerfile์ ์ฌ์ฉํ ์ปจํ ์ด๋ ๊ธฐ๋ฐ ํ๊ฒฝ์์ ๋น๋ ๋ฐ ์คํ
- FastAPI ๊ธฐ๋ฐ ๋ฐฑ์๋ ์๋ฒ ์ฝ๋ ๊ตฌ์ฑ
- Railway์ ๋ฐฑ์๋ ์๋ฒ ๋ฐฐํฌ ๋ฐ ์๋ํฌ์ธํธ
์ต์ข ์ ์ผ๋ก API ํ์ดํ๋ผ์ธ ๊ตฌ์ฑ ๋ฐ ์คํํ์์ต๋๋ค.
- ๋ฐ์ดํฐ ์ค๋น ๋จ๊ณ์์ download_files_only.py ์คํฌ๋ฆฝํธ๊ฐ ์คํ ๋จ๊ณ์์
gdown์ ํ์ฉํ์ฌ 800MB์ ๋ฌํ๋ ๋์ฉ๋ ๋ฐ์ดํฐ ๋ฐ ๋ชจ๋ธ ํ์ผ์ Google Drive์์ ๋ค์ด๋ก๋ํฉ๋๋ค. ์ด ๊ณผ์ ์ ๋น๋ ์๊ฐ ์ด๊ณผ(10๋ถ)๋ฅผ ํํผํ๊ธฐ ์ํด Procfile (ํน์ start.sh)์ ์ํด ์๋ฒ ์คํ ๋ช ๋ น ์ด์ ์ ๋ถ๋ฆฌ๋์ด ์คํ๋ฉ๋๋ค. ๋ค์์ผ๋ก ๋ชจ๋ธ ๋ก๋ฉ ๋จ๊ณ์์ ๋ค์ด๋ก๋๋ ํ์ผ๋ค์ api_server.py๊ฐ ์์๋ ๋ CPU ๋ฒ์ ์ PyTorch๋ฅผ ์ฌ์ฉํ์ฌ ๋ฉ๋ชจ๋ฆฌ์ ๋ก๋๋ฉ๋๋ค. - FastAPI ํ๋ ์์ํฌ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์๋ฒ๊ฐ ๊ตฌ์ถ๋์ด ๋์ ์ฑ๋ฅ์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ง์ํฉ๋๋ค
/v1/check_wallet์๋ํฌ์ธํธ๊ฐ ์ ์๋์ด ์์ผ๋ฉฐ, ์ด๋ ์ง๊ฐ ์ฃผ์ ๋๋ ํธ๋์ญ์ $\text{ID}$ ๋ชฉ๋ก์ ๋ฐ์ ๋ถ์์ ์์ฒญํฉ๋๋ค. - Pydantic ๋ชจ๋ธ์ธ WalletRequest๋ฅผ ์ฌ์ฉํ์ฌ ์์ฒญ ๋ณธ๋ฌธ(txIds: list[str])์ ๋ฐ์ดํฐ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์๋์ผ๋ก ์ํํฉ๋๋ค.
- ์ต์ข ์ ์ผ๋ก, API์ ํต์ฌ ๋ก์ง์ธ check_wallet ํจ์ ๋ด๋ถ์์ ํธ์ถ๋๋ run_pipeline ํจ์๊ฐ ํธ์ถ๋์ด ์ ๋ฌ๋ฐ์ ํธ๋์ญ์ ID๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ก๋๋ GNN ๋ชจ๋ธ ๋ฐ ๋ฐ์ดํฐ๋ฅผ ํ์ฉํ์ฌ ์ํ ํ์ง ๋ถ์์ ์คํํ์ฌ [๋ฐ์ดํฐ ๋งคํ โ ๋ชจ๋ธ ์ถ๋ก โ ๋ถ์ ๊ฒฐ๊ณผ ๋ฐํ]์ ์ ์ฒด ๊ณผ์ ์ด ํตํฉ๋์ด, ์ฌ์ฉ์๊ฐ ์์ฒญํ ํธ๋์ญ์ ID์ ๋ํ ์ํ ์ ์ ๋ฐ ๋ถ์ ๊ฒฐ๊ณผ๋ฅผ JSON ํํ๋ก ๋ฐํํฉ๋๋ค.