完整程式碼可在 GitHub 專案中找到:Finetune-30-days-demo / day-7
在前幾天,我們的訓練流程仍然是直接跑 python train_lora.py
。這樣做雖然簡單,但在實務上馬上遇到三個問題:
如果我們想讓專案真正往「平台化」邁進,必須先解決這三個問題。
換句話說,Celery + Redis 是最小成本、卻能帶來最大平台效益的組合。
新增 app/tasks/
與 app/api.py
:
app/
├── tasks/
│ ├── __init__.py # Celery 初始化與配置
│ └── training.py # LoRA 訓練任務
└── api.py # FastAPI API 介面
在 app/tasks/__init__.py
裡,設定 Celery 與 Redis:
celery_app = Celery(
"finetune_tasks",
broker="redis://localhost:6379/0",
backend="redis://localhost:6379/0"
)
後續又加上了 集中化配置(celery_config.py
)與 Redis 連線檢查,確保 worker 啟動前環境可用。
在 app/tasks/training.py
定義非同步任務,並加上狀態更新:
@celery_app.task(bind=True)
def train_lora_task(self, config: dict):
self.update_state(state="STARTED", meta={"progress": "initializing"})
result = run_training(config)
return {"status": "completed", "result": result}
用 FastAPI 建立兩個端點:
/train
:提交新訓練 → 回傳 task_id
/task/{id}
:查詢任務狀態 → 回傳 PENDING/STARTED/SUCCESS/FAILURE
/train
請求 → 立即回傳 task_id
/task/{id}
→ 得到即時狀態與結果透過 Celery + Redis,我們讓訓練流程具備了非同步執行、同時處理多個實驗的能力,並且能即時追蹤任務狀態。這不僅解決了阻塞與併發的問題,也替後續功能(像是進度條、詳細訓練指標)建立了基礎。
更重要的是,Day 7 讓系統正式從「單機腳本」邁向「平台級服務」:使用者不再需要等待,系統則具備橫向擴展的能力,只要增加 worker 就能處理更多任務。這是任務平台化的第一步,也為未來的前端 UI 串接、任務追蹤與錯誤恢復等功能鋪好了路。
📎 AI 協作記錄:今日開發指令
請幫我在專案中新增「任務排程基礎」功能,目的是把 LoRA 訓練流程改為非同步執行。
需求:
1. 使用 Celery + Redis 實作任務排程
- Celery worker 負責執行訓練
- Redis 作為 broker 和 backend
2. 把訓練流程包成一個 Celery 任務 (train_lora_task)
- 任務會回報狀態 (PENDING, STARTED, SUCCESS, FAILURE)
3. 建立 FastAPI API 端點
- POST /train → 建立任務並回傳 task_id
- GET /task/{id} → 查詢任務狀態與結果
4. 更新 Makefile,新增啟動 Redis、Celery Worker、FastAPI API 的指令
5. 確保程式結構清楚,新增 app/tasks/ 目錄來管理 Celery 相關檔案
請完成上述修改,讓我可以:
- 提交訓練任務
- 在背景執行訓練
- 查詢任務的執行情況
請幫我把 LoRA 訓練流程改成非同步執行,使用 Celery + Redis + FastAPI。目標是實作一個最小可行版本(MVP),只需要做到以下:
1. 建立 Celery 應用(app/tasks/__init__.py),使用 Redis 當 broker 與 backend。
2. 建立一個訓練任務(app/tasks/training.py),包裝 train_lora,並能回傳簡單結果(例如 val_loss、val_acc)。
3. 建立 FastAPI API(app/api.py),提供:
- POST /train → 提交任務,回傳 task_id
- GET /task/{id} → 查詢任務狀態(PENDING、STARTED、SUCCESS、FAILURE)
4. 更新 Makefile,新增 start-services、start-worker、start-api 指令。
5. 確保提交訓練後,API 不會被阻塞,可以查詢任務狀態。
請只做最小範例,不需要進度條、不需要資料庫紀錄。