跳轉至

第 1 章 · 收集與清洗 Pre-training 資料

本章你會學到

  • Pre-training 資料到底是什麼、從哪裡來、用什麼單位衡量
  • 為什麼「清洗」比「收集」還重要(垃圾進,垃圾出)
  • 一條真實可用的清洗流水線:抽取 → 語言辨識 → 品質過濾 → 去重 → 去個資 → 去有害 → 去污染
  • 繁體中文特別會踩到的坑(簡繁混雜、資料稀缺)

1.1 先講白話:什麼是 pre-training 資料?

想像你要培養一位博學的新同事。在教他做任何具體工作之前,你會先讓他把公司的圖書館、網路上的百科、報章雜誌、技術手冊……全部讀過一遍。他讀的這一大堆文字,就是 pre-training(預訓練)資料

模型從這些文字裡,自己歸納出:

  • 語言怎麼運作(文法、語氣、標點)
  • 世界的常識(台北是台灣的首都、水在 100°C 沸騰)
  • 各領域知識(法律、醫學、程式碼……)

重點:模型不是「查」資料,是「讀」進去變成能力

訓練完之後,這些文字並不會像資料庫一樣被存起來供查詢;它們會被「消化」成模型的能力。所以當初讀了什麼、讀得乾不乾淨,直接決定這位同事的底子

資料量的單位是 token,不是「字數」

模型不是一個字一個字看,而是把文字切成 token(詞元)——大約是「一個字塊」。

  • 英文:unbelievable 可能被切成 un + believ + able 三個 token。
  • 中文:常常一個字就是一個 token,有時兩三個字一組。

現代大模型的預訓練資料動輒 數兆(trillion)個 token。(1)

  1. 舉例:HuggingFace 的 FineWeb 資料集約 15 兆 token;Meta 的 Llama 3 用了超過 15 兆 token 預訓練。這是「把整個網路讀很多遍」的等級。

為什麼你該記住 token?

因為資料量、訓練成本、API 費用、模型能吃多長的輸入,全部都用 token 計價與計算,不是用「幾個字」。跨部門溝通時,講 token 才對得上頻道。


1.2 資料從哪裡來?

來源 例子 特點
網頁爬取 Common Crawl(公開的全網頁存檔) 量最大、最髒,需要大量清洗
百科 Wikipedia、百科全書 品質高、結構清楚,但量有限
書籍 / 論文 電子書、arXiv 論文 長文、深度知識,需注意版權
程式碼 GitHub 公開 repo 訓練「寫程式」能力的關鍵
問答 / 論壇 Stack Overflow、PTT、Dcard 口語、真實對話語氣
政府 / 開放資料 法規、公報、開放資料平台 正式、可信、授權清楚

繁體中文的現實難題:好資料很稀缺

全世界高品質的繁體中文文字,遠比英文或簡體中文少。這代表兩件事:

  1. 我們更需要把有限的繁中資料清乾淨、用好,一滴都不能浪費。
  2. 從網路撈到的「中文」常常混著簡體——若不處理,會教出一個簡繁不分、甚至用語像對岸的模型。(詳見 1.9 繁中專章

1.3 為什麼「清洗」比「收集」還重要?

一句業界老話:Garbage in, garbage out(垃圾進,垃圾出)

原始網頁裡塞滿了:導覽列、廣告、亂碼、重複複製的內容、色情與仇恨言論、別人的電話與 Email、甚至……考試的答案(這會讓後面的評測作弊)。

如果不清洗,這位新同事等於是在充滿雜訊和錯誤資訊的環境裡自學長大。

清洗是一個「漏斗」:撈得多,留得少

清洗流程會層層過濾,最後只留下一小部分精華。以 HuggingFace FineWeb 為例,從 Common Crawl 原始網頁一路過濾後,最終可用的高品質資料常常只剩不到 10%

flowchart TD
    A["🌐 原始網頁存檔<br/>Common Crawl(100%,超髒)"] --> B["① 抽正文<br/>去掉廣告/導覽列/HTML"]
    B --> C["② 語言辨識<br/>只留目標語言"]
    C --> D["③ 品質過濾<br/>丟掉亂碼/太短/垃圾"]
    D --> E["④ 去重<br/>刪掉重複與近似內容"]
    E --> F["⑤ 去個資 PII<br/>遮蔽電話/Email/身分證"]
    F --> G["⑥ 去有害內容<br/>色情/仇恨/詐騙"]
    G --> H["⑦ 去污染<br/>剔除評測考題"]
    H --> I["✨ 乾淨語料<br/>(常常只剩 <10%)"]
    style A fill:#ffebee,stroke:#c62828,color:#b71c1c
    style I fill:#e8f5e9,stroke:#2e7d32,color:#1b5e20

接下來逐步拆解這條流水線。


1.4 ① 抽取正文(Text Extraction)

原始網頁是一坨 HTML,裡面真正有價值的正文可能只佔一小塊,其餘是選單、廣告、頁尾、Cookie 提示……這一步要把「正文」精準摳出來。

  • 常用工具:trafilatura、jusText、resiliparse、readability。
  • 目標:留下文章本體,丟掉樣板(boilerplate)

做不好會怎樣?

如果正文抽取失敗,模型會讀進一堆「立即註冊 / 加入購物車 / 上一則下一則」,學到一嘴的廣告詞。


1.5 ② 語言辨識(Language Identification)

把每份文件標上語言,只留下你要的(例如 zh-Hant 繁體中文)。

  • 常用工具:fastText 語言辨識模型lid.176)、CLD3、langdetect。
  • 這一步會給每份文件一個「是這個語言的信心分數」,低於門檻就丟掉。

繁中的魔鬼細節

大多數語言辨識工具只會判斷「這是中文(zh)」,不會分繁體 / 簡體。要做繁中模型,得再加一層簡繁判斷(例如用 OpenCC 比對字形,或統計簡繁特徵字)。這點非常容易被忽略。


1.6 ③ 品質過濾(Quality Filtering)

即使語言對了,內容也可能是亂碼、關鍵字堆砌、或毫無資訊量的垃圾。品質過濾有三種常見做法,通常會搭配使用

用一組「常識規則」把明顯的垃圾濾掉。業界最有名的是 Gopher 規則C4 規則,例如:

  • 文件太短(少於 N 個字)或太長 → 丟
  • 平均每個詞太長 / 太短 → 可能是亂碼
  • 符號(#...)對文字的比例太高 → 丟
  • 重複行、重複段落佔比太高 → 丟
  • 含有大量「lorem ipsum」占位文字 → 丟
  • 結尾有標點的句子比例太低 → 可能是清單/導覽列
示意:一個 Gopher 風格的品質過濾器(簡化版)
def passes_quality(text: str) -> bool:
    words = text.split()
    n = len(words)

    # 規則 1:長度要合理(太短沒資訊、太長常是灌水)
    if n < 50 or n > 100_000:
        return False

    # 規則 2:平均詞長要像正常文字(亂碼常會爆掉)
    mean_word_len = sum(len(w) for w in words) / n
    if not (3 <= mean_word_len <= 10):
        return False

    # 規則 3:重複行佔比過高 → 多半是樣板或洗版
    lines = text.splitlines()
    if lines and (1 - len(set(lines)) / len(lines)) > 0.30:
        return False

    # 規則 4:符號 vs 文字比例(# 與 ... 太多 → 導覽列/亂碼)
    symbol_ratio = (text.count("#") + text.count("...")) / max(n, 1)
    if symbol_ratio > 0.10:
        return False

    return True

優點:極快、可解釋、免訓練。缺點:規則很「粗」,會誤殺也會漏抓。

先用乾淨文字(如 Wikipedia)訓練一個很輕量的語言模型(常用 KenLM),再拿它去「讀」每份文件:

  • 讀起來很順(困惑度低) → 像正常文章 → 留。
  • 讀起來很卡(困惑度高) → 像亂碼/垃圾 → 丟。

這是 Facebook CCNet 流水線的核心做法。

訓練一個小分類器來打分:

  • 正例:高品質文字(維基、書籍、優質教育內容)
  • 負例:隨機網頁

讓分類器學會「什麼像好內容」,再對全體資料打分、留高分的。HuggingFace 的 FineWeb-Edu 就是用一個「教育價值」分類器,篩出特別適合學習的網頁——實測能顯著提升模型表現。

給非工程師的重點

品質過濾沒有唯一標準答案,是「規則 + 統計 + 模型」多管齊下、反覆調參的工程活。每多濾掉一批垃圾,模型的底子就乾淨一分。


1.7 ④ 去重(Deduplication)

網路上同一篇文章常被轉貼、鏡像、複製上百次。若不去重,模型會對重複內容「死背」,浪費算力又傷害品質。

去重層級 抓什麼 方法
完全重複 一字不差的複製 對整份文件算雜湊值(hash),一樣就刪
近似重複 只改幾個字、換個標題 MinHash + LSH、SimHash
子字串重複 長文中夾帶的重複段落 後綴陣列(suffix array)精確比對

MinHash + LSH 是什麼?(一分鐘版)

直接兩兩比對「所有文件相不相似」會慢到天荒地老(數十億份文件)。MinHash 把每份文件壓成一小串指紋,LSH 則讓「指紋相近」的文件被快速分到同一桶,只需在桶內比對。這樣就能在可接受的時間內找出海量近似重複。

去重也有副作用

去太兇會誤刪合理的重複(例如法律條文、常見問候語),反而傷害資料多樣性。「去到剛剛好」本身就是一門調校功夫。


1.8 ⑤⑥⑦ 去個資、去有害、去污染

這三步是「責任與公平」的把關,跨部門同事尤其該懂。

  • ⑤ 去個資(PII Removal)


    用規則 + 模型偵測並遮蔽電話、Email、身分證字號、信用卡、地址等個人資訊。

    • 工具:正則表達式、Microsoft Presidio
    • 為什麼重要:涉及個資法與隱私,也避免模型「背出」某人的真實資料。
  • ⑥ 去有害內容(Safety Filtering)


    移除色情、仇恨、暴力、詐騙、垃圾廣告。

    • 工具:黑名單(如 UT1 網址清單)+內容分類器。
    • 為什麼重要:模型會模仿它讀到的東西;髒東西讀進去,就會吐出來。
  • ⑦ 去污染(Decontamination)


    評測考題從訓練資料裡剔除。

    • 做法:比對訓練資料與各大 benchmark 的 n-gram 重疊。
    • 為什麼重要:如果考卷混進了教材,模型考高分只是作弊背答案,不代表真本事。第 3 章會再呼應這點。

去污染 = 學術誠信

你不會讓學生拿到考卷去準備期末考。去污染就是確保「訓練」和「考試」的資料井水不犯河水,評測數字才可信。


1.9 繁體中文專章:最容易踩的坑

繁體中文模型時,除了上面通用流程,還要特別處理:

  1. 簡繁洩漏:撈到的「中文」網頁常混著簡體,或整篇是簡體轉繁的機器翻譯。若不濾除,模型會學到簡繁不分、用語不道地(例如講「軟件」而非「軟體」、「視頻」而非「影片」)。
    • 對策:語言辨識後再加簡繁判斷;必要時用 OpenCC 統一,或直接丟掉高簡體比例的文件。
  2. 在地知識稀缺:台灣的法律、地名、歷史、流行文化,在全網語料中比例極低。
    • 對策:主動蒐集台灣在地來源(政府開放資料、本地新聞、論壇),提高在地內容佔比。
  3. 量少所以更要乾淨:因為好的繁中資料本來就少,每一份的品質權重都更高,清洗與去重要更謹慎,避免把珍貴資料誤殺。

1.10 真實世界的資料集與工具

常被拿來參考的大型語料

語料 規模 特點
Common Crawl 全網頁存檔 最原始、最髒的起點
C4 ~750GB Google 清洗過的網頁語料
The Pile ~825GB 22 種來源混合
RefinedWeb 兆級 token 證明「純網頁+狠清洗」也能很強
FineWeb / FineWeb-Edu ~15 兆 token 目前最受歡迎的開源網頁語料之一
Dolma ~3 兆 token AI2 完整開源,含清洗流程

把上述步驟串起來的開源框架

  • datatrove(HuggingFace):模組化的大規模清洗流水線。
  • Dolma toolkit(AI2):完整開源的清洗工具。
  • data-juicer(阿里):上百種可組合的資料處理算子。
  • CCNet(Meta):語言辨識 + 困惑度過濾的經典流程。

本章 checklist

拿到一批 pre-training 資料,先問自己這幾題:

  • 正文有沒有抽乾淨?(沒混廣告/導覽列)
  • 語言對不對?繁中有沒有濾掉簡體?
  • 品質過濾做了嗎?(規則 / 困惑度 / 分類器)
  • 去重了嗎?(完全重複 + 近似重複)
  • 個資遮蔽了嗎?
  • 有害內容移除了嗎?
  • 去污染了嗎?(評測考題有沒有混進來)

小結

Pre-training 資料決定模型的底子。收集只是起點,清洗才是真功夫——它同時關乎品質、成本、法遵與評測公平性。下一章,我們看模型有了底子之後,怎麼教它「好好回話」。

前往第 2 章:SFT 資料集