Bộ checkpoint AI nội soi tiêu hóa
Repository này phát hành 7 checkpoint Ultralytics YOLO26m đã được xác minh SHA256 cho các tác vụ phân loại ảnh và phân đoạn tổn thương nội soi. Đây là các mô hình nghiên cứu/kỹ thuật, không phải thiết bị y tế và không được dùng để chẩn đoán hoặc thay thế bác sĩ.
Phạm vi release: 7 checkpoint gồm
anatomy,quality,mode,gastric,esophageal,esophagitisvàulcer. Modelpolyp(hạng mục 1.4.2) cố ý không có trong release này vì checkpoint đó chưa được xác minh lại SHA256 và phạm vi hiện tại mới chỉ là phân loại nhị phân, chưa đáp ứng đầy đủ phát hiện vị trí/subtype.
Sanitization: Các artifact công khai đã được làm sạch metadata trước khi phát hành. Tensor model, loại tác vụ và
names/thứ tự lớp được giữ nguyên; các đường dẫn hệ thống tệp nội bộ ban đầu đã được loại bỏ. SHA256 và byte size trong manifest/checksum là của chính các artifact đã làm sạch này.
Repository không chứa ảnh, video, tên, mã bệnh nhân hay metadata bệnh nhân. Các file được phát hành trong repository này theo GNU Affero General Public License v3.0 (AGPL-3.0-only), có tính đến giấy phép/phần mềm bên thứ ba; xem LICENSE và NOTICE.
Phạm vi giấy phép phần mềm/checkpoint phải được phân biệt với quyền dữ liệu và quyền sử dụng lâm sàng:
- Ultralytics YOLO và các checkpoint tạo bằng Ultralytics chịu các điều khoản AGPL-3.0, trừ khi người triển khai có một giấy phép Ultralytics Enterprise riêng phù hợp. Việc phát hành này không cấp thay giấy phép Enterprise.
- Dataset/ảnh lâm sàng dùng để huấn luyện không được phát hành. AGPL-3.0 của code/checkpoint không cấp quyền truy cập, sao chép, tái phân phối hoặc tái sử dụng dữ liệu nguồn, và không thay thế chấp thuận đạo đức, đồng ý của bệnh nhân hay quy định bảo vệ dữ liệu.
- Nhãn
research-onlyvà cảnh báo không dùng chẩn đoán là giới hạn về bằng chứng/đích sử dụng, không phải một điều khoản bổ sung sửa đổi AGPL-3.0. Không có tuyên bố rằng model đã được cấp phép như thiết bị y tế.
Danh sách model và kết quả hiện có
| Hạng mục | File | Tác vụ | Lớp | Bằng chứng kỹ thuật hiện có |
|---|---|---|---|---|
| 1.4.1 | weights/anatomy-yolo26m-cls.pt | Classification | 10 vị trí giải phẫu | Test Top-1 95,86%, macro-F1 95,82% (555 ảnh) |
| 1.4.3 | weights/quality-yolo26m-cls.pt | Classification | dat, khong_dat | Test 39/44 = 88,64%; tập test còn nhỏ |
| 1.4.3 | weights/mode-yolo26m-cls.pt | Classification | BLI, FICE, LCI, WLI | Test Top-1 99,64%, macro-F1 99,63% (555 ảnh) |
| 1.4.4 | weights/gastric-yolo26m-seg.pt | Instance segmentation | suspected_gastric_neoplasm | Val mask mAP50-95 0,652; chưa có test khóa cho checkpoint m |
| 1.4.5 | weights/esophageal-yolo26m-seg.pt | Instance segmentation | suspected_esophageal_neoplasm | Val mask mAP50-95 0,528; chưa có test khóa |
| 1.4.6 | weights/esophagitis-yolo26m-seg.pt | Instance segmentation | esophagitis_etiology_unverified | Test mask mAP50 0,361, mAP50-95 0,108 (243 ảnh); còn yếu |
| 1.4.7 | weights/ulcer-yolo26m-seg.pt | Instance segmentation | ulcer_htt_unverified_site_stage | Test mask mAP50 0,440, mAP50-95 0,157 (76 ảnh); còn yếu |
Các số liệu trên chỉ phản ánh split kỹ thuật hiện có. Chúng không phải bằng chứng hiệu năng lâm sàng và không nên được so sánh trực tiếp giữa các model có dataset/split khác nhau.
Cài đặt và tải model an toàn
python -m pip install "ultralytics==8.4.155" "huggingface_hub>=0.25"
Checkpoint PyTorch .pt có thể sử dụng cơ chế pickle và phải được coi là mã có khả năng thực thi. Chỉ load sau khi (1) khóa đúng một revision bất biến bằng full commit SHA và (2) so khớp SHA256 chính xác với MODEL_MANIFEST.json của chính revision đó. Không dùng main, tag có thể di chuyển, hoặc bỏ qua bước checksum.
Ví dụ tải và xác minh một model classification:
import hashlib
import re
from huggingface_hub import hf_hub_download
from ultralytics import YOLO
REVISION = "<FULL_40_CHARACTER_COMMIT_SHA>"
EXPECTED_SHA256 = "<64_CHARACTER_SHA256_FROM_MODEL_MANIFEST>"
if not re.fullmatch(r"[0-9a-f]{40}", REVISION):
raise RuntimeError("Set REVISION to the immutable full Hugging Face commit SHA")
if not re.fullmatch(r"[0-9a-f]{64}", EXPECTED_SHA256):
raise RuntimeError("Set EXPECTED_SHA256 from MODEL_MANIFEST.json at that revision")
weight = hf_hub_download(
repo_id="Anbinh93/cancer_prediction",
filename="weights/mode-yolo26m-cls.pt",
revision=REVISION,
)
digest = hashlib.sha256()
with open(weight, "rb") as checkpoint:
for chunk in iter(lambda: checkpoint.read(1024 * 1024), b""):
digest.update(chunk)
if digest.hexdigest() != EXPECTED_SHA256:
raise RuntimeError("Checkpoint SHA256 mismatch; refusing to load")
model = YOLO(weight)
print(model.names) # Luôn đọc thứ tự lớp từ checkpoint.
results = model.predict(source="endoscopy_frame.jpg", verbose=False)
Ví dụ model segmentation (dùng hash tương ứng của file gastric):
import hashlib
import re
from huggingface_hub import hf_hub_download
from ultralytics import YOLO
REVISION = "<FULL_40_CHARACTER_COMMIT_SHA>"
EXPECTED_SHA256 = "<64_CHARACTER_SHA256_FROM_MODEL_MANIFEST>"
if not re.fullmatch(r"[0-9a-f]{40}", REVISION):
raise RuntimeError("Set REVISION to the immutable full Hugging Face commit SHA")
if not re.fullmatch(r"[0-9a-f]{64}", EXPECTED_SHA256):
raise RuntimeError("Set EXPECTED_SHA256 from MODEL_MANIFEST.json at that revision")
weight = hf_hub_download(
repo_id="Anbinh93/cancer_prediction",
filename="weights/gastric-yolo26m-seg.pt",
revision=REVISION,
)
digest = hashlib.sha256()
with open(weight, "rb") as checkpoint:
for chunk in iter(lambda: checkpoint.read(1024 * 1024), b""):
digest.update(chunk)
if digest.hexdigest() != EXPECTED_SHA256:
raise RuntimeError("Checkpoint SHA256 mismatch; refusing to load")
model = YOLO(weight)
results = model.predict(
source="endoscopy_frame.jpg",
conf=0.25, # Giá trị minh họa, không phải ngưỡng lâm sàng đã thẩm định.
verbose=False,
)
for result in results:
boxes = result.boxes
masks = result.masks
Thứ tự lớp anatomy
Checkpoint anatomy lưu thứ tự lớp sau (ID 0–9):
0: 1 Hầu họng
1: 10 Tá tràng
2: 2 Thực quản
3: 3 Tâm vị
4: 4 Thân vị
5: 5 Phình vị
6: 6 Hang vị
7: 7 Bờ cong lớn
8: 8 Bờ cong nhỏ
9: 9 Hành tá tràng
Thứ tự này phản ánh metadata nhúng trong checkpoint và không phải thứ tự số tự nhiên. Client phải đọc model.names, không hard-code hoặc tự sắp xếp lại nhãn.
Kiểm tra toàn vẹn
Sau khi tải đủ các file vào đúng cấu trúc thư mục:
sha256sum --check SHA256SUMS
Trên macOS:
shasum -a 256 --check SHA256SUMS
Metadata máy đọc được, byte size, task, class order và metric nằm trong MODEL_MANIFEST.json. Sau khi repository được upload, hãy mở trang Files and versions, sao chép full commit SHA của revision đã duyệt vào REVISION, rồi lấy đúng trường sha256 của artifact tương ứng từ manifest tại cùng revision. Các placeholder trong ví dụ cố ý làm chương trình dừng trước khi load nếu người dùng chưa pin revision/hash.
Ánh xạ FastAPI
Docker image API dùng chung: anbinh933/cancel_prediction:latest. Mỗi service mount đúng một checkpoint read-only tại /models/model.pt.
| Service | Port mặc định | Endpoint inference | Weight |
|---|---|---|---|
anatomy | 8001 | POST /api/v1/predictions | anatomy-yolo26m-cls.pt |
quality | 8003 | POST /api/v1/predictions | quality-yolo26m-cls.pt |
mode | 8004 | POST /api/v1/predictions | mode-yolo26m-cls.pt |
gastric | 8005 | POST /api/v1/segmentations | gastric-yolo26m-seg.pt |
esophageal | 8006 | POST /api/v1/segmentations | esophageal-yolo26m-seg.pt |
esophagitis | 8007 | POST /api/v1/segmentations | esophagitis-yolo26m-seg.pt |
ulcer | 8008 | POST /api/v1/segmentations | ulcer-yolo26m-seg.pt |
Override checksum khi dùng weight từ Hugging Face
Các SHA256 mặc định hiện có trong inference_api/docker-compose.yml thuộc các checkpoint nội bộ trước sanitization. Bảy artifact tải từ Hugging Face đã được sanitizer ghi lại metadata nên có SHA256 mới. Nếu mount weight từ repository này mà không override, readiness sẽ cố ý trả 503 vì checksum không khớp.
Sao chép đúng block sau vào file .env đang dùng để triển khai Compose (các biến này không phải secret):
ANATOMY_MODEL_SHA256=0fe6726526b79e323ee82f7fafc0a6eddbd97d5963d4f6f82cf52db1eaabaf2c
QUALITY_MODEL_SHA256=eca7b6682adb84532f736e647ee60de569dfd16aa44546c3a312b2940dbb2316
MODE_MODEL_SHA256=e0d106ccc91c90f081a252400f2e62ae2e1589b9ec5eeda3fd33eb9a77f19451
GASTRIC_MODEL_SHA256=50dfd60ff67e77c31257c60a460990409b5d876d91eb4f73bdcfcc4bf3c1a715
ESOPHAGEAL_MODEL_SHA256=a9cb807e56622bb9a71edc394775bd3f2dbc5fab56d64bf9e7f9d512f9a63d8c
ESOPHAGITIS_MODEL_SHA256=dc1e4f5aed603f5ce1b74cdee3c4e08e726903c944d8079e4ed080a902568397
ULCER_MODEL_SHA256=3e3d8097d6b243be34f3d607f81e550c504daef2005c9ab298372a5c8ba51b66
Cùng nội dung có sẵn trong HF_SHA256_OVERRIDES.env.example. Sau khi cập nhật .env, recreate các service để Compose truyền checksum mới vào container.
Model polyp và service port 8002 vẫn tách riêng, không thuộc bảy artifact Hugging Face này. Không dùng các giá trị trên cho POLYP_MODEL_SHA256; chỉ triển khai polyp sau khi checkpoint riêng đã được xác minh SHA256.
Swagger của mỗi service nằm tại /docs; health endpoints là /health/live và /health/ready.
Giới hạn và sử dụng có trách nhiệm
- Các split hiện chưa có patient/exam ID chắc chắn, nên chưa loại trừ hoàn toàn leakage giữa các ca/cùng bệnh nhân.
- Dataset tổn thương chủ yếu chỉ gồm ảnh dương tính. Các metric hiện tại không đo đầy đủ false-positive rate trên video hoặc ca bình thường.
- Ontology tổn thương chưa được bác sĩ duyệt đầy đủ. Các hậu tố
suspectedvàunverifiedlà cố ý và không phải kết luận chẩn đoán. - Model
qualitymới được đánh giá trên 44 ảnh test; không đủ để khẳng định khả năng tổng quát hóa. modephân loại từng ảnh WLI/BLI/LCI/FICE, chưa nhận diện sự kiện chuyển mode theo chuỗi thời gian.anatomyphân loại toàn khung hình, không trả bounding box cho vị trí giải phẫu.- Cần đánh giá ngoại viện, split theo bệnh nhân/ca, tập âm tính được thẩm định, calibration và quy trình quản lý rủi ro trước mọi thử nghiệm lâm sàng.
- File PyTorch
.ptchỉ nên được tải từ nguồn tin cậy và phải được đối chiếu SHA256 trước khi load.