Resonance Lab · W01 Lab Note

DistilBERT 拆解:三次 push,兩個環境坑,才拿到 0.83

三路對決分數最高的是 DistilBERT,但這個分數得來不易——連續兩次 push 都失敗,第三次才真正跑完。

這篇解什麼問題

微調一個 transformer 模型,理論上流程很簡單:切資料、tokenize、丟進 Trainer、跑幾個 epoch。實際在 Kaggle 的 GPU 環境上跑,會遇到哪些理論上不會寫進教科書、但現場一定會踩到的環境問題。

我怎麼做

模型是 distilbert-base-uncased,跟 Route A、C 用同一份 80/20 切分(random_state=42,分層抽樣),max_length 設 128(推文本來就短,不需要更長),訓練 2 個 epoch。

第一次 push,直接死在讀資料這一步:

FileNotFoundError: [Errno 2] No such file or directory: '/kaggle/input/nlp-getting-started/train.csv'

原因是猜錯了掛載路徑。kernel-metadata.json 裡用 competition_sources 掛比賽資料時,實際掛載位置是 /kaggle/input/competitions/<slug>/,不是直覺以為的 /kaggle/input/<slug>/——這兩者只差一層目錄,但沒查文件很難猜對。改成先試兩個候選路徑,都沒有再往 /kaggle/input/ 底下遞迴找 train.csv,找不到才報錯並把目錄內容印出來,之後不會再靠猜。

第二次 push,資料讀對了,訓練卻直接爆掉:

torch.AcceleratorError: CUDA error: no kernel image is available for execution on the device

查了才知道,Kaggle 這次配到的加速器是 Tesla P100(運算能力 sm_60),但環境預裝的 PyTorch 版本只編譯了 sm_70 以上架構的 CUDA kernel。麻煩的地方是 torch.cuda.is_available() 依然回傳 True——程式不會在一開始就報錯,會一路跑到真正呼叫 CUDA 運算的那一刻才炸掉,而且已經吃掉一段訓練時間。

第三次,在正式訓練前先加一個探測:用一個一維 tensor 跑一次簡單的加法運算,包在 try/except 裡。能跑成功才真的用 GPU;跑不成功,TrainingArguments 直接切 use_cpu=True,整批訓練改在 CPU 上進行。這次順利撐過前兩次都會死掉的時間點,完整跑完。

結果與數據

CPU 上跑完 2 個 epoch,耗時 2064.8 秒(約 34.4 分鐘),本地驗證 F1 是 0.81487;提交 Kaggle 後,public leaderboard 分數是 0.83052,三條路線裡最高。

一句話結論

分數是三路裡最高的,但這個「最高」不是靠模型架構贏來的——是靠一個能自動偵測環境不相容、乾淨退回 CPU 的容錯機制,才沒有讓一個純粹的硬體版本問題毀掉整個實驗。