狀態(2026-07-11):主線 模組 Servo(真實 PHM FMCRD 資料集,健康分類 + 退化值回歸)已完整重訓 (
placeholder=false):留出測試分類 macro-F1 0.819、DV 回歸 R² 0.944,附可獨立重驗的資料溯源(CRC32 指紋 +GET /servo/provenance)。(特徵組自 engineered→full 轉正前為 macro-F1 0.757、R² 0.937,演進記錄見docs/MODULE_SERVO_PLAN.md§11。)FMCRD 為高擬真模擬資料集(非真實工廠遙測)。 另含四條對照軌(A/B/B+/C)、AI 訓練模擬器、LLM 維護助理、RAG 知識庫、即時監控 demo,以及 MLOps 閉環 (串流監控→告警→漂移偵測→自動重訓→驗證閘門→版本 registry,見 §5.1–5.4)。主前端為 Next.js Command Center。
🚀 線上 Demo:Next.js Command Center(主前端) · Streamlit(對照 / fallback)
端到端預測性維護原型,以真實 PHM 伺服馬達退化資料(模組 Servo) 為主線,另含四條對照軌補上不同失效模式 與感測模態。定位為維護決策輔助:產出故障風險、健康分數與人類可讀的維護建議,不對馬達下達控制命令。
- 是:以運轉條件估計故障風險 / 健康分數、以振動趨勢偵測退化起點並估 RUL、依規則產生維護建議的決策輔助工具。
- 不是:即時馬達控制器、可跨工況泛化的精準 RUL 回歸器、或已在實廠長期資料上驗證的成熟系統。
| 模組 | 資料集 | 感測模態 | 目標 | 真實性 |
|---|---|---|---|---|
| Servo(主線) | PHM FMCRD | 多通道聚合特徵 | 健康分類 + DV 回歸 | 高擬真模擬 |
| C(最貼近馬達) | Paderborn | 定子電流 MCSA + 振動 | 故障分類(人工→真實泛化) | 真實 PMSM 試驗台 |
| B / B+ | IMS / XJTU-SY | 振動 run-to-failure | 健康退化 + RUL / 多軌跡泛化 | 真實軸承退化 |
| A(僅方法基礎) | UCI AI4I 2020 | 靜態製程參數 | 故障二元分類 | 合成資料 |
誠實限制:A 為合成資料;IMS 為單軌跡不宣稱可泛化、不做深度 RUL 回歸;Paderborn 為故障分類(非 RUL)、屬試驗台 子集 MVP。細節見
docs/MODULE_SERVO_PLAN.md、docs/DATA_PROVENANCE.md。
FinalProject/
├── config.yaml # 集中設定(路徑 / 特徵組 / 門檻 / LLM)
├── requirements{,-dev,-dl}.txt # slim / 完整開發 / +torch
├── Dockerfile / docker-compose.yml / .github/workflows/ci.yml
├── data/raw/ # ai4i2020.csv、ims/xjtu/paderborn/servo(不進 git)
├── src/ # data / features / models / monitor / servo / llm / knowledge / ui / utils
├── app/ # backend/main.py(FastAPI,全端點)+ streamlit_app.py(fallback)
├── web/ # Next.js Command Center(主前端)
├── outputs/ # figures / metrics / models / reports
├── docs/ # 模組規劃 / 結果 / 資料溯源 / 部署 runbook
└── tests/ # pytest(151 通過 / 1 依環境跳過)
CRISP-DM:Data → src/data/、scripts/run_eda.py;Modeling → src/models/train.py;Deployment → web/、app/、docs/DEPLOYMENT.md。
已在 Python 3.10–3.14(Windows)測試;CI 於 3.11 / 3.12 驗證。
git clone <your-repo-url> && cd FinalProject
python -m venv .venv
.venv\Scripts\Activate.ps1 # Windows(macOS/Linux: source .venv/bin/activate)
pip install -r requirements-dev.txt # 完整環境(訓練 + FastAPI + 測試)其他組合:雲端 / Streamlit 用 slim
requirements.txt;離線深度學習用requirements-dl.txt(多裝 torch)。xgboost/lightgbm為選用,安裝失敗可註解掉會自動略過。資料集:AI4I 從 UCI 下載ai4i2020.csv放到data/raw/; IMS / XJTU / Paderborn / Servo 原始資料不進 git,見data/README.md。
python scripts/run_eda.py # EDA 圖表 → outputs/figures/
python -m src.models.train # 10 模型 × 5 特徵組比較 → best_model.joblib
python -m src.models.evaluate # 混淆矩陣 / ROC / PR + 重生 MODEL_CARD.md
python -m src.models.train_failure_types # 第二階段:故障類型分類器
python -m src.models.tune # Optuna 調參(前 3 名,15 trials × 3-fold)
python -m src.models.predict # 單筆 CLI 推論範例5 個特徵組定義於 config.yaml::feature_sets(A_baseline / B_engineered / C_selectkbest_top8 / D_rfe_top8 / E_rf_importance_top8);最佳模型以 F1 挑選。
uvicorn app.backend.main:app --host 0.0.0.0 --port 8000 # FastAPI 後端(Swagger: /docs)
cd web && npm install && \
NEXT_PUBLIC_API_BASE_URL=http://localhost:8000 npm run dev # Next.js 主前端 → :3000
streamlit run app/streamlit_app.py # Streamlit fallback → :8501前端涵蓋 Command Center 戰情室、Servo 五頁(儀表板 / 模擬器 / 欄位解釋 / LLM 助理 / 知識庫)、模組 A/B/B+/C 與即時監控雷達。
| 路由 | Method | 說明 |
|---|---|---|
/health、/model_info、/metrics |
GET | 存活狀態 / 最佳模型資訊 / 比較表 |
/predict、/predict/batch、/batch_predict |
POST | 模組 A 單筆 / What-if / CSV 批次 |
/ims/*、/xjtu/*、/paderborn/* |
GET/POST | 模組 B / B+ / C 結果 |
/monitor/scenarios、/monitor/stream |
GET | 即時監控回放 / SSE 串流 |
/servo/predict、/servo/fleet、/servo/provenance |
GET/POST | Servo 健康估測 / 機群 / 資料溯源 |
/servo/model_info |
GET | 當前 active 模型版本資訊(來自 registry,含 model_version) |
/servo/alerts、/servo/work_orders |
GET | 機群告警事件 / 衍生維修工單 |
/servo/assistant/*、/knowledge/* |
GET/POST | LLM 維護助理 / 知識庫檢索 |
串流端點另置:FMCRD replay 的
GET /servo/stream(SSE)由獨立的 replay 發布端scripts/servo_replay_publisher.py提供(自成一個服務、不在主後端/docs),見 §5.1。 模型 registry 版本切換與漂移偵測為 CLI 驅動(servo_model_registry/run_drift_demo.py,見 §5.3–5.4), 主後端不另開對應端點;告警事件由告警引擎寫入outputs/alerts/<date>.jsonl。
curl -X POST http://localhost:8000/predict -H "Content-Type: application/json" \
-d '{"type":"L","air_temperature_K":298.1,"process_temperature_K":308.6,
"rotational_speed_rpm":1551,"torque_Nm":42.8,"tool_wear_min":108}'LLM 金鑰(選用):助理可離線運作;要接真 LLM,複製 .env.example 為 .env 並填任一家金鑰(依序嘗試
GROQ_API_KEY → OPENROUTER_API_KEY → GEMINI_API_KEY → ANTHROPIC_API_KEY)。順序可於 config.yaml::llm 調整;.env 不進 git。
MLOps 閉環一鍵 demo:整條「偵測→重訓→閘門→切換→消化」劇本可用單一指令重現(fresh-clone 即可跑、 結束自動 reset 回 v1 可重複執行):
python scripts/run_drift_demo.py
# 預期:HI 退化不誤觸、注入 gain×1.3 漂移 FIRED、閘門 PASS → active = v2、v2 對同一漂移段已消化,
# 漂移資料上分類 macro-F1 v1 0.44 → v2 0.83(細節與誠實揭露見 §5.4)。狀態(2026-07-11):S1 + S1b 完成——真實 FMCRD replay 素材抽取 + SSE 發布端 + 視窗聚合接收端, 健康狀態隨 replay 段落 LN → LO → HI 演進(DV degradation_score 0.05→0.26→0.75、風險 Low→High)。 S1b 驗證抽稀對模型無害(極值特徵偏差 <0.01%、串流 vs 離線預測一致率 100%),W/S 已鎖定 run 循環對齊 (見
docs/MODULE_SERVO_PLAN.md§12.1)。完整儀表板留待 S2。
沿用即時監控的 SSE 骨架(data: {json} 串流),資料源換成真實 FMCRD 測試資料、模型接參考模型 predict_servo:
# 一次性:從 FMCRD zip 抽出 LN/LO/HI replay 素材到 data/demo/replay/(需原始 zip;無 zip 會清楚報錯)
python scripts/extract_replay_segments.py
# 終端 1:發布端(逐列以 RAW_COLUMNS schema 發布,預設加速重播 LN→LO→HI)
python scripts/servo_replay_publisher.py # SSE:/servo/stream
# 終端 2:接收端(滑動視窗→複用 build_feature_table/aggregate_run 的 21 維 full 特徵→predict_servo→逐視窗打印)
python scripts/servo_replay_consumer.py發布端另有 --mode fake 合成模式:僅供管線連通性測試,其資料不在模型訓練分布內、預測輸出無效
(接收端會標記 ⚠ 假數據,預測無效)。demo 一律使用 FMCRD replay 模式。 視窗 W(預設 = 一個 6s run 循環,
對齊訓練的 per-run 聚合粒度)與步長 S 均可於 config.yaml::servo_replay.window 調整。全程唯讀既有模型。
狀態(2026-07-11):完成。在串流管線上加告警遲滯引擎與 Streamlit 即時監控頁。告警遲滯(連續 N=3 窗 High 觸發、M=3 窗回落解除)與狀態燈平滑以 S1b 實測的 LN↔LO 門檻閃爍為依據,非教科書預設。 詳見
docs/MODULE_SERVO_PLAN.md§13。
python scripts/servo_replay_publisher.py # 終端 1:SSE 發布端(同 §5.1)
streamlit run app/streamlit_app.py # 終端 2:側邊欄「Servo 即時監控」頁
# 或用 CLI 觀察告警事件:python -m src.monitor.alert_engine- 狀態燈用「近 3 窗多數決」平滑避免 LN/LO 邊界閃爍,但同屏保留逐窗原始預測——平滑是顯示層決策、非竄改 模型輸出(模型真實不確定性同屏可見)。
- 主告警遲滯觸發後,事件立即寫
outputs/alerts/<date>.jsonl(含model_version),工單草稿由 LLM 助理背景 生成(多供應商 + 離線 fallback),LLM 失敗不阻塞告警。consistency_warning走獨立矛盾提示、不觸發主告警。 - 參數:
config.yaml::servo_alert(N/M、狀態燈平滑窗數、model_version)。
狀態(2026-07-11):完成。模型版本 registry(
models/registry/)、載入集中化 (servo_model_registry.load_active())、驗證閘門(完整性 / 煙霧 / 留出指標 / AE 單調)與一鍵重訓管線。predict_servo對外介面與輸出不變、下游零感知。詳見docs/MODULE_SERVO_PLAN.md§14。
python -m src.models.servo_model_registry --list # 列版本 + active
python scripts/retrain_pipeline.py # 重訓 → 驗證 → PASS 轉正 v<n+1> / FAIL 擋下
python scripts/retrain_pipeline.py --dry-run # 訓練+驗證,不切換 active
python scripts/retrain_pipeline.py --data-config '{"train_frac":0.1}' # 爛候選演練(閘門會擋下)
python -m src.pipeline.validation_gate models/registry/candidate_<ts> # 單獨跑閘門- 每版含
metrics.json(留出 macro-F1 / DV R²、特徵組、模型檔 CRC32、訓練 config 快照、FMCRD 溯源、時間戳)。 - 閘門容忍帶(
config.yaml::servo_gate,預設 0.005)吸收訓練隨機性、不放行實質退化。 - 回滾:改
models/registry/registry.json的active_version(或servo_model_registry.set_active('v1')), 服務重載後predict_servo//servo/model_info/ 告警model_version全鏈路切回。
狀態(2026-07-11):完成。閉環 = 漂移偵測 → 自動重訓 → 閘門 → 版本切換。核心原則 退化 ≠ 漂移: 漂移 AE(PCA 線性、全類別擬合)讓退化在分布內、只有真 off-manifold 位移才觸發。詳見
docs/MODULE_SERVO_PLAN.md§15。
python scripts/run_drift_demo.py # 一鍵劇本:正常→注入漂移→DRIFT→重訓→閘門→v2→消化→reset
python scripts/validate_drift_blindspot.py # 核心發現:noisy LO 為流形內偏移,重建式偵測抓不到- 驗收(實跑):HI 退化不誤觸、注入感測器漂移(gain×1.3)觸發、重訓後 v2 消化;漂移資料上分類 macro-F1 v1 0.44 → v2 0.83。
- 誠實揭露:(1) noisy LO domain shift 是分類邊界難度、非重建式可測漂移(與 §11 三重證據互證,存
drift_blindspot.json); (2) 注入漂移為模擬真實感測器增益故障;(3) 信心訊號在 OOD 上不降反升(自信地錯),故重建式偵測才必要; (4) demo 標籤現成,真實工廠漂移後新資料需標註流程。
每筆預測回傳 failure_probability / predicted_class / health_score / risk_level / maintenance_advice,
health_score = round((1 - p) * 100, 2)。風險門檻(config.yaml::risk):<0.3 低 / 0.3–0.7 中 / ≥0.7 高;規則式建議
門檻(config.yaml::advice_thresholds,實作於 src/models/predict.py):溫差 ≥12 K、扭矩 ≥55 Nm、刀具磨耗 ≥200 min、
轉速 ≤1300 rpm。因正樣本僅約 3%,以 Recall / F1 / ROC-AUC / PR-AUC 共同評估、Pipeline 內處理避免 data leakage;所有建議為決策輔助非控制命令。
docker compose up -d # FastAPI:8000(含 /health healthcheck)+ Streamlit:8501
docker compose downdata/ 與 outputs/ 為 bind mount,可在容器內訓練(docker compose run --rm api python -m src.models.train)。GCP VM / Vercel + Hugging Face Space 完整部署 runbook 見 docs/DEPLOYMENT.md。
.github/workflows/ci.yml 於 push / PR 到 main、master 執行三個 job:
- test(Python 3.11 / 3.12):
compileall語法檢查 +pytest(151 通過 / 1 跳過;用合成 fixture 與已提交產物,不需原始大檔)。 - web(Node 24):
eslint+tsc --noEmit+next build。 - docker:buildx 建映像並執行 import smoke test。本機重現:
compileall→pytest→docker build -t pmm-app:ci .。
- AI4I 為合成資料、無時間維度,指標無法外推實廠;RUL 由 B(IMS)/ B+(XJTU)補上。監督式「絕對小時數 RUL」跨壽命 尺度 / 工況泛化受限,B+ 延伸 E1(壽命正規化 / z-score / CORAL)部分改善(LOCO R² −1.22 → −0.92)但未解決。
- 決策門檻預設 0.5、維護建議為靜態門檻,正式部署應依成本模型與機台個別校準。
- 已完成延伸:B+ E1–E3、模組 C(Paderborn 人工→真實泛化 MVP + CE1/CE4);推遲:其他資料集 / 更強領域自適應 / ESP32(未來實場接入 / IoT demo)/ 成本敏感門檻。
MLOps 閉環(已完成):Servo 主線已具端到端的預測性維護 MLOps 閉環——FMCRD replay SSE 串流監控(§5.1)→
告警遲滯引擎(§5.2)→ 漂移偵測(重建誤差;退化 ≠ 漂移,退化在分布內、僅真 off-manifold 位移觸發,§5.4)→
自動重訓 → 驗證閘門(完整性 / 煙霧 / 留出指標 / AE 單調,§5.3)→ 模型版本 registry 與一鍵回滾。整條劇本由
scripts/run_drift_demo.py 一鍵重現、fresh-clone 可重跑(驗收:漂移資料上分類 macro-F1 v1 0.44 → v2 0.83)。
- 授權:MIT License(見
LICENSE)。 - UCI AI4I 2020 Dataset:https://archive.ics.uci.edu/dataset/601/ai4i+2020+predictive+maintenance+dataset
- scikit-learn · FastAPI · Streamlit · CRISP-DM 1.0 (Chapman et al., 2000)
