Pipeline phân tích cardiac CT tại chỗ theo nguyên tắc ML định vị ROI pericardium, phép tính HU deterministic ra con số (model không bao giờ regress ra số — mọi giá trị đều audit được). Đợt này scale silver-label lên 1000 ca + retrain trên DGX Spark GB10.
| Thành phần | Giá trị | Ghi chú |
|---|---|---|
| Board / SoC | NVIDIA DGX Spark — GB10 Grace-Blackwell | CPU ARM Cortex-X925 + A725; unified memory |
| Kiến trúc | aarch64 (ARM64) | KHÔNG phải x86 — Docker kéo image bản linux/arm64 |
| GPU compute | Blackwell, compute cap 12.1 (sm_121) | verify matmul chạy thật trên GB10 |
| CUDA / driver | CUDA 13.3 (container) · driver 580.159.03 (kernel) | CUDA forward-compat mode ENABLED |
| Container GPU | nvcr.io/nvidia/pytorch:26.06-py3 → voriacare-dgx:eat | torch 2.13.0a0+nv26.06, CUDA=True, device "NVIDIA GB10" |
| Deps (image) | TotalSegmentator 2.15.0 · nnunetv2 2.8.1 · SimpleITK 2.5.5 · scikit-image 0.26 · nibabel 5.4.2 | torch NGC giữ nguyên (không bị pip thay) |
| Flags container | --gpus all · --ipc=host · -v $IMG_DIR:/data:ro | nnUNet_compile=0 (an toàn trên aarch64) |
Khác Jetson: dùng NGC pytorch (không l4t-pytorch) và --gpus all (không --runtime nvidia).
Tag 24.08 trong runbook gốc không hỗ trợ Blackwell GB10 → chọn 26.06 (tag mới nhất, có bản arm64, sm_121).
Giải nén từ 1-200 … 801-1000 (mỗi range = split-zip .z01..z04 + segment cuối) bằng recombine zip -s 0 --out rồi
unzip chỉ lấy *.img.nii.gz. Kiểm tra toàn vẹn gzip 0 lỗi. IMG_DIR=/media/hientm/data_NDGD/ImageCAS/extracted/all.
ImageCAS = CTA cản quang + label lòng vành (label không dùng cho EAT).
Chạy run_eat_batch.py --limit 5 --fast để kiểm chứng end-to-end trên GB10 trước khi scale.
TotalSegmentator whole-heart → ROI pericardium proxy (convex-hull per-slice + dilation EDT 3mm) → EAT deterministic.
Container eat-batch chạy nền, resumable (CSV ghi tăng dần, skip ca đã xong).
Cập nhật (auto): 2026-07-09 17:34 — 1000/1000 ca, ~25.9 s/ca (tổng 7.05h). Output: out/eat_1000.csv +
silver masks masks/<id>/{heart,pericardium_roi}.nii.gz (trên ổ 2.7TB). Con số cập nhật khi sinh lại báo cáo.
Trong ROI pericardium: đếm voxel HU ∈ [−190, −30] × thể tích voxel → EAT (mL) + mean HU. Không có model regress số. Test phantom: chính xác tuyệt đối (1000 voxel × 0.25 mm³ = đúng 0.25 mL; window loại đúng biên).
vc_eat/measure.pyvc_eat/harness.pyvc_eat/postprocess.py — keep-largest-CCtests/test_measure_eat.py ✓3d_fullres, fold 0, nnUNet_compile=0 (nnUNet dirs trên ổ 2.7TB). Dừng sớm ở epoch 604/1000 vì
EMA pseudo-Dice đã plateau (12 lần cải thiện cuối chỉ bò 0.9714→0.9747, mỗi lần ~0.0001–0.0003) — chạy hết 1000 epoch
không đáng cho nhãn silver. Dùng checkpoint_best (best-EMA) làm model cuối. Đang chạy validation để lấy Dice held-out thật.
Cập nhật train (auto): —. Nguồn: nnU-Net training_log trong results/…/fold_0/ (đọc trực tiếp từ file, không phụ thuộc stdout buffer).
export_onnx.py (checkpoint_final=best-EMA) → ONNX opset-18 (external-data, 123MB) → trtexec → verify_trt.py
trên GB10 Blackwell. Engine per-GPU (ONNX portable, .plan gắn GPU).
--fp16 — mạng mặc định
strongly-typed, precision lấy từ kiểu trong ONNX. Nên engine này là FP32/TF32 (không phải FP16 như tên file pericardium_fp16.plan
giữ lại cho tương thích script). Trên GB10, TF32 tensor-core vẫn nhanh; parity với torch gần tuyệt đối. Muốn FP16 thật trên TRT11 cần
export ONNX kiểu FP16 (ghi nhận là bước sau).Chạy test_trt_vs_hull.py trên 50 ca held-out (fold_0 val, model không thấy khi train): so ROI của
model TRT (đã clean keep-largest-CC) với ROI silver hull, và EAT hai bên.
| Metric (n=50) | Giá trị | Diễn giải |
|---|---|---|
| Dice ROI mean / median / min | 0.959 / 0.962 / 0.886 | model tái tạo hull rất trung thực trên ca chưa thấy |
| EAT MAE / MAPE | 4.74 mL / 4.5% | sai lệch EAT nhỏ (tốt hơn baseline Jetson 6.86 mL) |
| EAT bias | −3.4 mL | model hơi thấp hơn hull — do clean_pericardium bỏ island → ROI nhỏ lại |
| Pearson r | 0.983 | tương quan EAT rất cao |
| EAT median (trt / hull) | 98.4 / 104.3 mL | — |
| Tốc độ | ~187 s/ca | 3d_fullres nặng; muốn nhanh cần 3d_lowres |
Màu Dice: ≥0.95 · 0.90–0.95 · <0.90. ΔEAT = EAT_trt − EAT_hull.
| # | Ca (held-out) | EAT_trt (mL) | EAT_hull (mL) | ΔEAT | Dice ROI | meanHU |
|---|---|---|---|---|---|---|
| 1 | 281 | 50.97 | 53.37 | -2.4 | 0.9557 | -84.0 |
| 2 | 199 | 51.32 | 56.92 | -5.6 | 0.95 | -91.5 |
| 3 | 19 | 58.96 | 60.44 | -1.47 | 0.9622 | -77.6 |
| 4 | 27 | 61.62 | 63.83 | -2.2 | 0.9599 | -89.1 |
| 5 | 240 | 68.58 | 70.99 | -2.41 | 0.9628 | -86.1 |
| 6 | 236 | 68.91 | 70.95 | -2.04 | 0.9561 | -87.8 |
| 7 | 254 | 73.9 | 77.33 | -3.43 | 0.9577 | -82.3 |
| 8 | 246 | 75.23 | 76.46 | -1.23 | 0.9622 | -82.5 |
| 9 | 203 | 79.05 | 83.59 | -4.53 | 0.9667 | -75.8 |
| 10 | 101 | 80.1 | 76.33 | 3.77 | 0.9532 | -83.9 |
| 11 | 266 | 82.26 | 89.24 | -6.98 | 0.9693 | -78.3 |
| 12 | 313 | 82.47 | 82.96 | -0.49 | 0.9692 | -88.6 |
| 13 | 157 | 82.71 | 85.02 | -2.31 | 0.9632 | -81.7 |
| 14 | 261 | 83.49 | 87.27 | -3.78 | 0.9546 | -86.1 |
| 15 | 1000 | 84.2 | 91.47 | -7.27 | 0.9693 | -80.7 |
| 16 | 152 | 85.4 | 89.16 | -3.76 | 0.9572 | -82.5 |
| 17 | 107 | 88.42 | 90.46 | -2.04 | 0.9604 | -78.4 |
| 18 | 228 | 88.68 | 87.04 | 1.64 | 0.9673 | -86.9 |
| 19 | 299 | 90.09 | 97.02 | -6.93 | 0.9592 | -81.4 |
| 20 | 220 | 91.61 | 99.34 | -7.73 | 0.9608 | -79.5 |
| 21 | 22 | 95.3 | 96.52 | -1.23 | 0.9734 | -76.9 |
| 22 | 201 | 96.74 | 103.95 | -7.21 | 0.9677 | -74.8 |
| 23 | 140 | 97.74 | 99.96 | -2.22 | 0.953 | -76.0 |
| 24 | 135 | 98.24 | 97.41 | 0.83 | 0.8932 | -96.3 |
| 25 | 194 | 98.39 | 110.13 | -11.74 | 0.9576 | -72.3 |
| 26 | 233 | 98.49 | 106.19 | -7.71 | 0.97 | -76.4 |
| 27 | 278 | 100.77 | 110.86 | -10.1 | 0.9543 | -81.2 |
| 28 | 192 | 101.83 | 104.59 | -2.75 | 0.9739 | -77.6 |
| 29 | 164 | 101.98 | 112.94 | -10.97 | 0.9632 | -78.4 |
| 30 | 197 | 102.19 | 104.71 | -2.52 | 0.9695 | -80.0 |
| 31 | 212 | 105.21 | 108.67 | -3.47 | 0.9721 | -73.9 |
| 32 | 113 | 105.84 | 100.21 | 5.63 | 0.9282 | -78.4 |
| 33 | 18 | 110.21 | 116.74 | -6.53 | 0.9618 | -88.3 |
| 34 | 285 | 111.57 | 116.65 | -5.08 | 0.9696 | -76.8 |
| 35 | 275 | 116.7 | 117.45 | -0.75 | 0.9616 | -80.3 |
| 36 | 297 | 117.35 | 126.19 | -8.85 | 0.9606 | -75.7 |
| 37 | 312 | 117.59 | 122.68 | -5.09 | 0.9617 | -76.3 |
| 38 | 128 | 120.25 | 123.21 | -2.95 | 0.9611 | -85.2 |
| 39 | 239 | 122.87 | 125.73 | -2.86 | 0.9665 | -81.6 |
| 40 | 149 | 127.71 | 129.93 | -2.22 | 0.9665 | -77.5 |
| 41 | 215 | 129.56 | 132.55 | -2.99 | 0.9725 | -78.3 |
| 42 | 218 | 132.79 | 149.39 | -16.6 | 0.9593 | -78.4 |
| 43 | 244 | 134.22 | 130.04 | 4.18 | 0.9655 | -78.5 |
| 44 | 146 | 136.18 | 138.49 | -2.31 | 0.959 | -80.4 |
| 45 | 267 | 136.51 | 144.87 | -8.36 | 0.9417 | -78.3 |
| 46 | 293 | 145.11 | 129.36 | 15.75 | 0.8862 | -76.9 |
| 47 | 222 | 147.5 | 146.44 | 1.06 | 0.9639 | -87.7 |
| 48 | 1 | 147.93 | 152.28 | -4.35 | 0.9639 | -79.1 |
| 49 | 277 | 148.3 | 154.47 | -6.17 | 0.9565 | -79.8 |
| 50 | 25 | 149.43 | 152.12 | -2.69 | 0.9734 | -82.5 |
out/test50_trt_vs_hull.csv.| Hạng mục (Jetson, 200 ca) | Kết quả | Ghi chú |
|---|---|---|
| Silver batch 200 ca | 98.2 mL median | 0 lỗi · 4.40h · ROI/heart 1.62× |
| nnU-Net 3d_fullres (250ep) | Dice 0.9596 | held-out 40 ca · epoch ~338s |
| nnU-Net 3d_lowres (100ep) | Dice 0.9716 | inference ~32s/ca · ~3× nhanh |
| TensorRT FP16 parity | Dice 0.9997 | ΔEAT < 0.11 mL · argmax 99.996% |
TotalSegmentator+hull+EDT bằng 1 forward pass exportable. EAT đúng lâm sàng vẫn cần gold pericardium label.| Vấn đề | Triệu chứng / nguyên nhân | Fix |
|---|---|---|
| Nhầm nền tảng | giả định x86 A100/H100 → thực tế GB10 ARM64 Blackwell | verify uname -m+torch.cuda, điều chỉnh toàn bộ lệnh |
| NGC tag quá cũ | pytorch:24.08 ra trước Blackwell → không có kernel sm_121 | dùng tag mới 26.06-py3 (bản arm64) |
| Split-zip không unzip thẳng | file vắt qua ranh giới part 4.3GB → member không đọc được | recombine zip -s 0 --out trước rồi unzip |
| Docker /dev/shm | mặc định 64MB → nnUNet dataloader "No space left" | --ipc=host |
| Triton (aarch64) | torch.compile có thể crash trên ARM | nnUNet_compile=0 |
| ngrok kiến trúc | runbook ghi "linux amd64" nhưng máy là ARM64 | cài ngrok linux arm64 |
| Đĩa / hạn chế | ổ / chỉ 173GB — không đủ cho 1000 ca + nnUNet | data + masks + nnUNet → ổ 2.7TB (bind-mount) |
voriacare-dgx:eat, torch giữ CUDA.Trang: index/status (trang này) · pipeline · gallery · algorithms · models (so sánh kiến trúc).
Gallery hiện dùng figures của model trước; figures 2D+3D từ model DGX sẽ sinh lại sau TRT.
run_eat_trt.py.