Pipeline phân tích cardiac CT tại chỗ theo thứ tự EAT → CAC → CCTA, chạy hoàn toàn on-device. Nguyên tắc xuyên suốt: ML định vị ROI, phép tính HU deterministic ra con số (model không bao giờ regress ra số — mọi giá trị đều audit được).
| Thành phần | Giá trị | Ghi chú |
|---|---|---|
| Board | Jetson AGX Orin Dev Kit, 32GB unified | full-res, không patch-based ở inference |
| OS / L4T | Ubuntu 22.04.5 · L4T R36.4.7 | = JetPack 6.2 |
| CUDA | 12.6 (nvcc 12.6.68), driver 540.4.0 | |
| TensorRT | 10.3 (host) · 10.4 (container) | khớp mục tiêu TRT10 |
| cuDNN / Python | 9.3 · Python 3.10 | |
| Container GPU | dustynv/l4t-pytorch:r36.4.0 → voriacare-l4t:eat | torch 2.4.0, CUDA=True, device "Orin" |
| I/O stack (host venv) | pydicom 3.0.2 · SimpleITK 2.5.5 · highdicom 0.27.0 | wheel aarch64 sẵn — không cần build |
Watched-folder worker: gom DICOM theo SeriesInstanceUID, debounce chờ series đủ, dựng volume 3D với HU đúng
(SimpleITK/GDCM sort không gian + áp Rescale Slope/Intercept), rồi verify HU.
RescaleSlope/Intercept, so voxelwise với output SimpleITK → bắt đúng bug "rescale không áp" (stored-value thay vì HU).
Còn treo: đường DICOM loader (GDCM) mới validate trên phantom — cần 1 series DICOM thật để đóng Phase 0 đúng nghĩa (ImageCAS là NIfTI nên không chạm đường này).
Matrix 512×512 đồng nhất; slices 206–275. HU-verify vững trên cohort thật. ImageCAS = CTA có cản quang + label lòng vành → hợp cho CCTA/coronary & anatomical prior; không dùng cho CAC (CAC cần CT non-contrast).
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.py — Bland-Altman + Dicetests/test_measure_eat.py ✓ImageCAS không có nhãn EAT/pericardium. Đường bootstrap: TotalSegmentator (whole-heart) → ROI pericardium proxy = convex-hull per-slice + dilation EDT 3mm. Proxy over-inclusive — đây là điểm cần gold label để sửa.
Output: out/eat_200.csv + silver masks masks/<id>/{heart,pericardium_roi}.nii.gz. Batch resumable (ghi CSV tăng dần).
Train segmenter thay chuỗi hull heuristic. Cấu hình: 3d_fullres, fold 0, trainer 250 epochs, patch (96,160,160).
| Metric | Giá trị | Diễn giải |
|---|---|---|
| ROI Dice (model vs hull) | 0.960 | model tái tạo trung thực hull |
| EAT MAE / MAPE | 6.86 mL / 6.3% | sai lệch nhỏ |
| Bias / Pearson r | +6.6 mL / 0.984 | hơi lớn hơn hull |
TotalSegmentator+hull+EDT bằng 1 forward pass, exportable.
EAT đúng lâm sàng vẫn cần gold pericardium label.| Stage | Kết quả |
|---|---|
| 1 · ONNX export | pericardium.onnx (123 MB) · argmax vs torch 99.996% |
| 2 · TRT FP16 engine | pericardium_fp16.plan (63 MB) · build 516s · ~123 ms/patch |
| 3 · Parity trên ca thật | Dice(TRT,torch) 0.9997 · EAT Δ < 0.11 mL → FP16 an toàn production |
| 4 · Wire-in | run_eat_trt.py: CT → TRT pericardium → EAT, self-contained |
3d_fullres → ~245 patch/volume + resample 512³ mới là nút cổ chai.
Fix: retrain low-res (3d_lowres, volume ~8× nhỏ hơn) → inference vài giây/ca thật sự.Mục tiêu: model 3d_lowres (spacing ~0.99×0.69×0.69, volume median 139×259×259) để inference nhanh vài giây/ca.
Lưu ý: nnU-Net chạy 250 iter/epoch cố định + patch size như nhau → thời gian train/epoch ≈ fullres; speedup ở inference.
nnUNetv2_preprocess -c 3d_lowres xử lý 0 ca (folder rỗng) → training vấp
infer_dataset_class assertion. Đang tách bước preprocess ra chạy riêng & xác minh ghi file trước khi train lại.| Vấn đề | Triệu chứng | Fix |
|---|---|---|
| SimpleITK dangling view | GetArrayView(ReadImage(...)) → segfault (view trỏ buffer đã free) | giữ ref Image, hoặc GetArrayFromImage (copy) |
| torch PyPI trên Jetson | cu130 wheel → cuda=False "driver too old" | dùng Jetson wheel trong l4t-pytorch |
| Docker /dev/shm | mặc định 64MB → dataloader "No space left on device" | --ipc=host |
| Triton thiếu (aarch64) | torch.compile crash "Cannot find triton" sau Epoch 0 | nnUNet_compile=0 |
| ROI dilation chậm | structuring-element 13×19×19 ngốn 3–4× thời gian/ca | distance-transform EDT (O(n), đúng mm) |
dicom_loader · hu_verify · series_watchermeasure · harness · pericardium
verify_hu · watch_ingest · scan_datasetrun_eat_batch · build_nnunet_dataset · train_pericardium.shexport_onnx · verify_trt · predict_trt · run_eat_trt