Spaces:
Paused
Paused
| # ============================================================ | |
| # Dockerfile — สูตรสร้างเครื่อง Linux ให้เหมือน Kaggle ที่เคยเทรนสำเร็จ | |
| # | |
| # ===== ต้องการอะไร ===== | |
| # detectron2 + Pose2Seg รันบน Windows ไม่ได้ -> ต้องมีเครื่อง Linux | |
| # แต่ Kaggle ยกกลับบ้านไม่ได้ (พอปิดโน้ตบุ๊กเครื่องถูกล้าง) | |
| # ไฟล์นี้คือ "สูตร" ที่เอาไปสร้างเครื่องแบบเดียวกันที่ไหนก็ได้ | |
| # | |
| # ===== ไฟล์นี้ทำอะไร ===== | |
| # บอก Hugging Face Spaces ว่าต้องลงอะไรบ้าง ก็อปไฟล์อะไรไปไหน แล้วรันคำสั่งอะไร | |
| # (แปลมาจากเซลล์ SETUP ของ notebooks/kaggle_finetune_densenet.ipynb) | |
| # | |
| # ===== วิธีคิด — ลำดับการลง สำคัญมาก ห้ามสลับ ===== | |
| # 1. torch ก่อน -> เพราะ detectron2 ต้อง compile ทับ torch ที่มีอยู่ | |
| # 2. detectron2 -> build จาก source (~5-10 นาที ช้าสุดในไฟล์นี้) | |
| # 3. lib ของแอป -> gradio, sklearn ฯลฯ | |
| # 4. numpy 1.26.4 ท้ายสุด -> เพราะขั้น 2-3 อาจดึง numpy 2.x มาทับ | |
| # ต้องกดกลับเป็น 1.26.4 เป็นขั้นสุดท้ายเสมอ | |
| # (numpy 2.0 ลบ np.mat ที่ Pose2Seg ใช้ -> ไม่กดกลับ = พัง) | |
| # ============================================================ | |
| FROM python:3.10-slim | |
| # ---------- ของระบบที่ต้องมี ---------- | |
| RUN apt-get update && apt-get install -y --no-install-recommends \ | |
| git \ | |
| build-essential \ | |
| libgl1 \ | |
| libglib2.0-0 \ | |
| ca-certificates \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # git = ไว้ clone detectron2 กับ Pose2Seg | |
| # build-essential= คอมไพเลอร์ C++ (detectron2 ต้อง compile ตอนลง) | |
| # libgl1/libglib = opencv ต้องใช้ ไม่มีแล้ว import cv2 พัง | |
| # ---------- สร้าง user ธรรมดา (HF Spaces แนะนำ ไม่ให้รันด้วย root) ---------- | |
| RUN useradd -m -u 1000 user | |
| USER user | |
| ENV HOME=/home/user \ | |
| PATH=/home/user/.local/bin:$PATH | |
| WORKDIR $HOME/app | |
| # ============================================================ | |
| # ขั้น 1: torch (CPU) — ต้องมาก่อน detectron2 | |
| # ============================================================ | |
| # ใช้ CPU เพราะ HF Spaces ฟรีไม่มี GPU (รูป 1 ใบใช้เวลา ~5-15 วินาที ยอมรับได้) | |
| RUN pip install --no-cache-dir --user \ | |
| torch==2.1.2 torchvision==0.16.2 \ | |
| --index-url https://download.pytorch.org/whl/cpu | |
| # ============================================================ | |
| # ขั้น 2: detectron2 — build จาก source (ช้าที่สุด ~5-10 นาที) | |
| # ============================================================ | |
| RUN pip install --no-cache-dir --user \ | |
| 'git+https://github.com/facebookresearch/detectron2.git' | |
| # ============================================================ | |
| # ขั้น 3: lib ของแอป | |
| # ============================================================ | |
| RUN pip install --no-cache-dir --user \ | |
| scikit-learn==1.6.1 \ | |
| opencv-python-headless \ | |
| pillow \ | |
| pandas \ | |
| joblib \ | |
| gradio | |
| # scikit-learn==1.6.1 = เวอร์ชันเดียวกับที่เทรน bmi_bundle.pkl (กันผลเพี้ยน) | |
| # opencv-headless = opencv แบบไม่มี GUI (เซิร์ฟเวอร์ไม่มีจอ ใช้ตัวเต็มจะพัง) | |
| # ============================================================ | |
| # ขั้น 4: กด numpy กลับเป็น 1.26.4 (ต้องเป็นขั้นสุดท้ายของการลง lib) | |
| # ============================================================ | |
| RUN pip install --no-cache-dir --user --force-reinstall numpy==1.26.4 | |
| # ===== หัวใจ: ถ้าลืมบรรทัดนี้ Pose2Seg จะพังตอน import (np.mat หายไปใน numpy 2.0) ===== | |
| # ============================================================ | |
| # ขั้น 5: เอา lib ของ Pose2Seg มาเติมใน repo | |
| # ============================================================ | |
| # repo 2DImage2BMI ขาด lib/transforms กับ lib/timer -> ต้อง clone Pose2Seg มาเอาเฉพาะ lib/ | |
| RUN git clone --depth 1 https://github.com/liruilong940607/Pose2Seg.git /tmp/pose2seg | |
| # ============================================================ | |
| # ขั้น 6: ก็อปไฟล์ของเราเข้าเครื่อง | |
| # ============================================================ | |
| COPY --chown=user 2DImage2BMI-main/ $HOME/app/2DImage2BMI-main/ | |
| RUN cp -r /tmp/pose2seg/lib $HOME/app/2DImage2BMI-main/lib && rm -rf /tmp/pose2seg | |
| COPY --chown=user models/ $HOME/app/models/ | |
| COPY --chown=user results/ $HOME/app/results/ | |
| COPY --chown=user *.py $HOME/app/ | |
| # ============================================================ | |
| # ขั้น 7: patch Detected.py (ตัด SCHP/PSP/CPM/CRFRNN ที่เราไม่มี) | |
| # ============================================================ | |
| RUN python patch_detected.py $HOME/app/2DImage2BMI-main/Detected.py | |
| # ถ้า patch ล้ม -> build ล้มทันที ดีกว่าไปพังตอนผู้ใช้กดปุ่ม | |
| # ============================================================ | |
| # ขั้น 8: บอก features.py ว่าไฟล์อยู่ไหน | |
| # ============================================================ | |
| ENV BMI_REPO=$HOME/app/2DImage2BMI-main \ | |
| POSE2SEG_PKL=$HOME/app/models/pose2seg_release.pkl \ | |
| DENSE_PT=$HOME/app/results/dense/dense_bmi_best.pt \ | |
| BUNDLE_PATH=$HOME/app/results/dense/bmi_bundle.pkl \ | |
| PORT=7860 \ | |
| PYTHONUNBUFFERED=1 | |
| # PYTHONUNBUFFERED=1 = ให้ print ออก log ทันที ไม่ค้างใน buffer (สำคัญตอนไล่ดู log บน HF) | |
| # ---------- ตรวจตอน build ว่า import ผ่านจริงไหม ---------- | |
| # ทำตรงนี้เพื่อให้รู้ตั้งแต่ตอน build ว่าพัง ไม่ต้องรอผู้ใช้กดปุ่มแล้วค่อยพบ | |
| RUN python -c "\ | |
| import sys; sys.path.insert(0, '$HOME/app/2DImage2BMI-main'); \ | |
| import numpy; print('numpy', numpy.__version__); \ | |
| import torch; print('torch', torch.__version__); \ | |
| import detectron2; print('detectron2 OK'); \ | |
| import cv2; print('cv2 OK'); \ | |
| import sklearn; print('sklearn', sklearn.__version__)" | |
| EXPOSE 7860 | |
| CMD ["python", "app.py"] | |