# 从网络构建微调数据集：从URLs到JSONL

一个好的微调90%依赖于数据集。这是从原始URLs到清洁JSONL的流程——大规模获取、去重、许可过滤，以及训练者实际期望的聊天格式。

微调的质量取决于你提供的数据，而微调中最难的部分几乎从来不是训练过程，而是构建一个干净的数据集。网络是这种数据最丰富的来源，但原始页面是混乱的、重复的、未标记的且法律上不均衡。本指南是从URLs到训练就绪JSONL的流程：你实际需要多少数据，如何大规模获取，如何清理和去重，如何处理许可，以及如何将其格式化为训练者期望的聊天结构。假设你正在从公共网络内容构建一个指令或聊天微调。

## 你实际上需要多少数据？

从现实的目标开始，这样你就不会过度或不足构建。一个产生合理结果的微调的实际最低限度是大约100行；对于稳固的性能，你通常需要超过1,000行。更多通常有帮助，但前提是它是干净的——一千个标记良好的例子胜过一万个嘈杂的例子。作为规模参考，经典的Alpaca数据集是52,000个指令/输出对，通过提示一个更强的模型生成。如果你使用一个大型模型生成合成例子，至少用十个手写例子来初始化它，以便它在生成更多之前学习你想要的确切结构和语气。

## 获取：从爬取到清洁markdown

在获取阶段的目标是清洁文本，而不是原始HTML。一个微调行需要页面的实质内容——文章、文档、问答——而不是导航栏、cookie横幅和广告标记，这些会污染一个天真的爬取。因此，爬取你的目标页面并在摄取时将其转换为markdown，这样可以在保留结构如标题和列表的同时去除样板。在任何实际的体量下，你都会遇到速率限制和IP封锁，因此通过一个旋转池路由爬取。一个[Scraper API](https://quantumproxies.io/scraper-api)可以直接返回markdown，一次调用即可完成清洁输出和抵抗封锁的双重任务，这就是为什么我们在我们的[为LLMs提供新鲜网络数据](https://quantumproxies.io/blog/feeding-llms-fresh-web-data-2026)指南中涵盖它。

```python
# Sketch: crawl target URLs to clean markdown, ready for shaping into rows.
import requests

API = "https://api.quantumproxies.io/v1/scraper/extract"   # returns markdown, handles rotation

def fetch_markdown(url):
    r = requests.post(API, json={"url": url, "format": "markdown"},
                      headers={"Authorization": "Bearer YOUR_KEY"}, timeout=120)
    return r.json()["payload"]["content"]

docs = [fetch_markdown(u) for u in seed_urls]   # clean text, no boilerplate
```

![从 URL 到微调数据集的流水线：通过轮换 IP 池把页面爬取为干净的 markdown，用精确哈希和近似重复检测进行清洗和去重，把每一行格式化为 JSONL messages，然后编写数据集卡片并留出评估集；卡片列出了过程中需要过滤掉的垃圾内容。](https://res.cloudinary.com/dmqliab0t/image/upload/f_auto,q_auto,w_1200/v1785335214/blog/generated/qp-b9-087-diag1.png)
*模型只会看到你的数据集，因此每一个去除垃圾的阶段都直接改善微调。*

## 训练者期望的JSONL格式

大多数现代微调工具默认使用对话式JSONL格式：每行一个JSON对象，每个对象都有一个`messages`数组，包含角色/内容对，其中角色是`system`、`user`和`assistant`，用户/助手轮流交替。这是Hugging Face和OpenAI风格的训练者摄取的聊天格式。较旧的指令数据集使用三字段形状（`instruction`、`input`、`output`）——适合单轮监督微调——也存在多轮对话格式，但它们可以干净地转换为消息形状。选择一个目标格式并将所有内容标准化为该格式。

```js
// One training example per line (.jsonl). Chat / messages format:
{"messages":[
  {"role":"system","content":"You classify support tickets by urgency."},
  {"role":"user","content":"My payment failed three times and the event is tomorrow."},
  {"role":"assistant","content":"high"}
]}
{"messages":[
  {"role":"system","content":"You classify support tickets by urgency."},
  {"role":"user","content":"How do I change my avatar?"},
  {"role":"assistant","content":"low"}
]}
```

将格式与训练目标匹配：原始文本用于持续预训练，指令加输出或多轮聊天用于监督微调，偏好方法的排序响应。如果你正在构建一个推理微调，保留问题和答案，但重写答案以包含你希望模型学习的思维链步骤。

## 清理：质量的决定因素

这是决定你结果的阶段，主要是乏味的过滤。永远不要假设网络来源或模型生成的行是正确的——检查它们。反复出现的失败模式是具体的，值得按名称检查：

- **标签不一致**：同一类别在一行中写为"Positive"，在另一行中写为"positive"——规范化大小写和拼写。
- **偏离目标的答案**：助手返回一个句子或一个后续问题，而不是你训练所需的确切标签或格式。
- **错误标记的行**：一个模糊的输入被分配了错误的输出——这是最具破坏性的一种噪音。
- **样板残留**：导航文本、cookie通知或"阅读更多"片段在markdown转换后幸存下来。
- **重复**：相同或几乎相同的例子增加了行数，并使模型倾向于重复内容。

一个好的习惯是保留清理前和清理后的JSONL，以便你可以衡量你去除了什么。并在类别之间平衡集合——一个过度代表的类别会教模型过度预测它。

## 去重和许可

网络数据充满了重复——联合文章、镜像文档、样板段落——重复悄悄地通过过度加权重复的内容损害微调。做两次遍历：通过对规范化文本进行哈希来进行精确匹配去重，以捕捉相同的行，然后进行近重复检测（如MinHash的相似性或分片技术）以捕捉精确哈希错过的改写副本。在许可方面，要有意识：并非所有公开的内容都可以自由使用。跟踪每个文档的来源和许可，过滤掉那些条款禁止训练使用的内容，并优先选择具有明确重用权限的来源。记录来源在爬取时比在混合后重构便宜得多。

[为LLMs获取清洁的网络数据](https://quantumproxies.io/web-data-for-llms)

## 合并、卡片和拆分

当你从多个来源提取时，将它们全部标准化为一种格式，并在训练前合并为一个统一的数据集——在组合集上进行一次干净的微调胜过在每个来源上顺序微调，这往往会侵蚀模型早期学到的东西。然后写一个数据集卡片：一个简短的记录，说明数据来自哪里，如何清理，其大小和标签分布，其许可，以及任何已知的限制。这使得数据集在几个月后可重现和可审计。最后，保留一个从未训练过的评估拆分，以便你可以诚实地衡量微调，而不是在模型记住的数据上评分。如果你正在为检索系统而不是微调提供数据，我们的[RAG管道指南](https://quantumproxies.io/blog/fresh-web-data-rag-pipelines)涵盖了同一问题的刷新方面。

![微调数据集规模的对数刻度图：合成生成至少需要十个手写种子示例，约 100 行是实际可用的下限，超过 1,000 行才能获得稳定的效果，经典的 Alpaca 数据集有 52,000 对；卡片强调，超过 1,000 行干净数据之后，质量比数量更重要。](https://res.cloudinary.com/dmqliab0t/image/upload/f_auto,q_auto,w_1200/v1785335214/blog/generated/qp-b9-087-diag2.png)
*大约100行以下，微调几乎学不到东西；超过1,000个干净行，质量胜过数量。*

## 常见问题解答

### 我需要多少行来微调一个LLM？

大约100行是合理结果的实际最低限度，超过1,000是稳固性能的好目标。更多通常有帮助，但前提是数据保持干净——一个较小、标记良好的集合胜过一个大的嘈杂集合。对于合成生成，至少用十个手写例子来初始化生成器，以便它首先学习你的确切格式。

### 微调数据应该是什么格式？

JSONL——每行一个JSON对象。大多数现代训练器默认使用带有`messages`数组的对话格式，包含系统/用户/助手角色-内容对。较旧的指令数据集使用指令/输入/输出字段。根据你的训练目标选择一个目标格式，并在训练前将每个来源标准化为该格式。

### 如何清理用于微调的爬取数据集？

将页面转换为markdown以去除样板，然后手动过滤常见的失败：标签不一致、偏离目标的答案、错误标记的行，以及剩余的导航或cookie文本。用精确哈希和近重复遍历去重，平衡类别，并保留原始和清理后的版本，以便你可以衡量你去除了什么。

### 我可以用任何网络内容来训练模型吗？

不是自动的——公开并不意味着可以自由使用。有些内容带有禁止训练使用的条款，个人数据有其自身的规则。在收集时跟踪每个文档的来源和许可，过滤掉任何条款不允许训练的内容，并优先选择明确许可的来源。这是一般信息，而非法律建议；对于商业数据集，请咨询法律顾问。

从网络构建微调数据集是一个过滤管道：获取清洁的markdown，将其塑造成训练者期望的消息格式，严格去重和标签检查，过滤许可，并记录结果。获取大约一千个干净行并保留一个诚实的评估拆分，这样你就可以将你的训练预算花在信号而不是噪音上。

[使用QuantumProxies的网络数据构建你的数据集](https://quantumproxies.io/web-data-for-llms)
