# ============================================================ # 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"]