staging real worker 轉 tflite 失敗:tflite→onnx 需要 import tensorflow,但 Dockerfile.real 當初為省 image 大小沒裝 TF(只驗過 onnx/bie/nef 輸入)。 改 services/workers/Dockerfile.real: - 加 tensorflow-cpu==2.13.1(Python 3.9 相容 + numpy<2 相容 + ktc TF compat patch 預期範圍的交集;-cpu 省 ~1.5GB CUDA) - 加 igraph==1.0.0(tree_structure.py 硬 import、pin 對齊本檔版本鎖哲學) - 補 typing-extensions>=4.8.0(TF 會把它降版打爆 fastapi import) - numpy<2 精確化為 numpy==1.23.5(落在原 <2 範圍 + TF 接受窗口、語意子集非破鎖) 本機驗證:image 4.36GB→5.71GB;tflite→onnx 通(產 188 節點合法 ONNX);既有 BIE→NEF 回歸產出同一顆真 NEF(621,956 bytes)、prebuild ldd 全 resolved。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
137 lines
8.0 KiB
Docker
137 lines
8.0 KiB
Docker
# Real Worker Dockerfile — 自帶 prebuild toolchain,可實際把 BIE→NEF 真實轉檔
|
||
#
|
||
# 與 Dockerfile.stub 的差異:本 image 內含 ktc/ 真實轉檔素材 + toolchain/prebuild
|
||
# 的 x86-64 編譯 binaries(batch_compile / kneron_nef_utils / model_converter),
|
||
# 並設好 USE_PREBUILD/LD_LIBRARY_PATH/PYTHONPATH,讓 import ktc + ktc.compile 走
|
||
# repo 自帶 prebuild 路徑(不抓系統 libs/compiler、libs/dynasty)。
|
||
#
|
||
# Build(從專案根目錄、本機 Docker daemon):
|
||
# docker build -f services/workers/Dockerfile.real -t kneron-worker-real:verify .
|
||
#
|
||
# 注意:build context 含 toolchain/prebuild (~2GB)。搭配「專案根 .dockerignore」
|
||
# (docker build 以專案根為 context,只讀 context 根目錄的 .dockerignore;不存在
|
||
# services/workers/.dockerignore)排除 libs/dynasty + libs/compiler(被 USE_PREBUILD
|
||
# 取代,省 ~3.2GB)。
|
||
|
||
# python:3.9 對齊既有 worker;bullseye(Debian 11, glibc 2.31) 對舊 toolchain
|
||
# (prebuild ELF 最低需求 GNU/Linux 3.2.0)相容性最佳。
|
||
FROM python:3.9-slim-bullseye
|
||
|
||
WORKDIR /app
|
||
|
||
# --- System libraries ---------------------------------------------------------
|
||
# opencv-python runtime: libgl1 / libglib2.0-0
|
||
# OpenMP / OpenBLAS(compiler binary 會用): libgomp1
|
||
# gfortran runtime(prebuild/lib 雖自帶 libgfortran.so.5,仍裝保險): libgfortran5
|
||
# 其餘缺的 .so 靠 image 內 `ldd toolchain/prebuild/batch_compile` 的 "not found" 補。
|
||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||
libgl1 \
|
||
libglib2.0-0 \
|
||
libgomp1 \
|
||
libgfortran5 \
|
||
ca-certificates \
|
||
procps \
|
||
file \
|
||
&& rm -rf /var/lib/apt/lists/*
|
||
|
||
# --- Python dependencies ------------------------------------------------------
|
||
# 1) queue / storage(consumer.py 需要)
|
||
# 2) worker 既有 requirements(fastapi/onnx/opencv…)
|
||
# 3) ktc → sys_flow / sys_flow_v2 + extract_bie_info + kneronnxopt module-load 額外
|
||
# 需要(全部由本機實跑 `import ktc` 逐個盤出):
|
||
# pandas blinker docopt snoop pyzipper dict_recursive_update beautifulsoup4
|
||
# jinja2 matplotlib tabulate commentjson IPython adjustText onnx_tool onnxsim
|
||
#
|
||
# 特別注意的版本鎖:
|
||
# - onnx==1.14.1:與 root requirements 一致;ktc/toolchain.py 對 onnx==1.7.0 會
|
||
# 關閉 730 支援,必須避開 1.7.0。
|
||
# - onnx_tool==0.7.0:未鎖時裝到的新版在 import 期會踩
|
||
# "unsupported operand type(s) for |: MessageMeta and type"(protobuf 衝突);
|
||
# 0.7.0 import 乾淨。
|
||
# - onnxsim==0.4.36(--only-binary):py3.9/bullseye 上新版 onnxsim 無 wheel、需
|
||
# cmake 從源碼編;0.4.36 有 prebuilt wheel,避免裝 build toolchain。
|
||
# 4) tflite 輸入格式轉檔(tflite→onnx,第一步 ktc.onnx_optimizer.tflite2onnx_flow)
|
||
# 需要 tensorflow + python-igraph(converter: libs/ONNX_Convertor/tflite-onnx):
|
||
# - tensorflow-cpu==2.13.1:挑此版的三重理由——
|
||
# (a) Python 3.9 相容:2.13.x 支援 py3.8–3.11;再新的 TF(2.16+)drop py3.9。
|
||
# (b) numpy<2 相容(最關鍵):TF 2.13.1 要求 numpy>=1.22,<=1.24.3(全 1.x),
|
||
# 與既有 prebuild 鏈的「numpy 1.x」硬需求一致;再新的 TF(2.16+)會拉
|
||
# numpy>=2 → 直接撞爆 prebuild 的 "numpy.core.multiarray failed to import"。
|
||
# (c) ktc 需求:ktc/onnx_optimizer_1_13.py 的 _get_tensor_details_compat patch
|
||
# 是為「較新 TF(tf.lite.Interpreter._get_tensor_details 需 subgraph_index,
|
||
# TF 2.5+ 引入)」寫的 → TF 2.13.1 落在此範圍、patch 正常生效。
|
||
# 選 -cpu 版:不需 GPU、省下 CUDA 相關 ~1.5GB。
|
||
# - igraph==1.0.0:converter 的 tree_structure.py:13 `from igraph import Graph` 硬
|
||
# import 需要(不裝→tflite→onnx 第一步 ModuleNotFoundError)。pin 死是為了
|
||
# reproducible build——igraph 是 tflite 鏈的硬依賴、裸裝 latest 未來重 build 可能
|
||
# 裝到行為改變的新版;1.0.0 是本次 build 實裝並驗證可跑的版本。
|
||
# - typing-extensions>=4.8.0:TF 2.13.1 會把 typing-extensions 降到 4.5.0
|
||
# (其 pin 是 <4.6),導致 fastapi 0.104.1 `import fastapi` 掛
|
||
# `cannot import name 'TypeAliasType'`。TF 對 typing-extensions 的上限只是
|
||
# *soft warning*(實測升到 4.15 後 tf 2.13.1 + tf.lite.Interpreter 仍正常),
|
||
# 故在 TF 之後把 typing-extensions 補回 >=4.8.0,修復 fastapi/pydantic。
|
||
# 5) numpy==1.23.5 最後裝並「釘死」:prebuild 鏈的 C-extension 以 numpy 1.x 編譯,
|
||
# numpy 2.x 會出 "numpy.core.multiarray failed to import"。1.23.5 同時滿足
|
||
# TF 2.13.1 的 numpy>=1.22,<=1.24.3 窗口 + 既有 prebuild/onnx 的 1.x 需求。
|
||
# 最後安裝確保不被 TF/其他套件連帶升級。
|
||
COPY services/workers/nef/requirements.txt /tmp/worker-requirements.txt
|
||
RUN pip install --no-cache-dir \
|
||
redis>=5.0 boto3>=1.28 \
|
||
&& pip install --no-cache-dir -r /tmp/worker-requirements.txt \
|
||
&& pip install --no-cache-dir \
|
||
"onnx==1.14.1" \
|
||
scipy \
|
||
pandas blinker docopt snoop \
|
||
pyzipper dict_recursive_update beautifulsoup4 jinja2 matplotlib tabulate \
|
||
commentjson IPython adjustText "onnx_tool==0.7.0" \
|
||
&& pip install --no-cache-dir --only-binary :all: "onnxsim==0.4.36" \
|
||
&& pip install --no-cache-dir "tensorflow-cpu==2.13.1" "igraph==1.0.0" \
|
||
&& pip install --no-cache-dir "typing-extensions>=4.8.0" \
|
||
&& pip install --no-cache-dir "numpy==1.23.5"
|
||
|
||
# --- Application + toolchain source ------------------------------------------
|
||
# 精準 COPY,避免把 libs/dynasty(2.0G) + libs/compiler(1.2G) 帶進來。
|
||
COPY ktc/ /app/ktc/
|
||
COPY vendor/ /app/vendor/
|
||
COPY services/ /app/services/
|
||
COPY toolchain/prebuild/ /app/toolchain/prebuild/
|
||
COPY libs/kneronnxopt/ /app/libs/kneronnxopt/
|
||
COPY libs/ONNX_Convertor/ /app/libs/ONNX_Convertor/
|
||
COPY libs/fpAnalyser/ /app/libs/fpAnalyser/
|
||
COPY E2E_Simulator/python_flow/ /app/E2E_Simulator/python_flow/
|
||
# 驗證用 fixtures + conftest(production 部署可拿掉,這裡為了在 image 內端到端跑)
|
||
COPY tests/ /app/tests/
|
||
|
||
RUN mkdir -p /data/jobs
|
||
|
||
# --- Toolchain / runtime environment(即 tests/conftest.py 的 production 化版本)---
|
||
ENV USE_PREBUILD=/app/toolchain/prebuild
|
||
ENV LD_LIBRARY_PATH=/app/toolchain/prebuild/lib
|
||
ENV PYTHONPATH=/app:/app/vendor:/app/libs:/app/libs/kneronnxopt:/app/E2E_Simulator/python_flow
|
||
ENV KTC_DISABLE_MP=1
|
||
|
||
# --- Worker runtime config ----------------------------------------------------
|
||
ENV WORKER_MODE=real
|
||
ENV REDIS_URL=redis://redis:6379
|
||
ENV JOB_DATA_DIR=/data/jobs
|
||
# STORAGE_BACKEND 刻意「不」在此 image 設預設值。
|
||
#
|
||
# 為什麼:consumer.py 第 52 行 `os.environ.get("STORAGE_BACKEND", "local")` 本身
|
||
# 已會 fall back 到 local。若這支真實版 image 又寫死 ENV STORAGE_BACKEND=local,會給
|
||
# 部署者「image 預設就能上雲」的錯覺;一旦 staging compose 漏設 STORAGE_BACKEND=minio,
|
||
# worker 會 *安靜* 走 local(產出寫 container 本機磁碟、不上 MinIO)→ 轉檔成功但
|
||
# visionA poll 拿不到結果(即 commit b8457dd / cbd1b9d 修過的同類隱患)。
|
||
#
|
||
# 處理姿態:
|
||
# - 本 image 不設預設 → 由 compose / 部署環境「顯式」提供。
|
||
# - staging(用 MinIO)必設 `STORAGE_BACKEND=minio`(見部署 checklist 硬性項)。
|
||
# - 本機 / dev 不設時,consumer.py 仍 fall back local,stub/local 開發流程不受影響。
|
||
# - 註:要根除 silent fallback 的最穩做法是在 consumer.py 對 WORKER_MODE=real 做
|
||
# fail-fast(漏設 minio 即報錯),但那屬 application code、需 backend 處理,
|
||
# 不在本 Dockerfile 範圍。
|
||
# STAGE: onnx / bie / nef(三個 worker 共用此 image,差在 entrypoint)
|
||
ENV STAGE=nef
|
||
|
||
# 用 shell form 以便 ${STAGE} 變數展開(三個 worker 共用 image、差在此變數)。
|
||
CMD ["sh", "-c", "python -m services.workers.${STAGE}.worker"]
|