社区供稿 | Reader-LM: 将原始 HTML 转换为干净 Markdown 的小型语言模型

文摘   2024-09-20 10:30   广东  

2024 年 4 月,我们发布了 Jina Reader,一个简单实用的 API,只需要在网址前面加个 r.jina.ai,就能把网页变成大型语言模型(LLM)喜欢的 Markdown 格式。

Jina Reader 背后的技术很复杂,但核心的“读取”部分相对简单:

首先,我们使用无头浏览器读取网页代码,接着用 Mozilla 的 Readability 提取主要内容,去掉头部、底部、导航栏、侧边栏等元素。再用正则表达式和 Turndown 库把清理好的 HTML 变成 Markdown。得到一个结构良好的 Markdown 文件后,LLM 就能轻松提取信息、做摘要和推理了。

Jina Reader 刚发布那几周,我们收到了大量用户反馈,主要是对内容质量的意见。有人觉得内容太详细,有人又嫌不够详细,还有人说 Readability 过滤器删错了东西,或者 Turndown 转换 HTML 有问题。还好,很多问题通过正则表达式和一些小技巧解决了。

但是,我们一直在思考:与其不停地修修补补(维护起来很麻烦,还不支持多语言),能不能直接用语言模型直接端对端地解决这个问题?

乍一看,用大型语言模型处理数据,似乎又贵又慢不划算。但如果我们用的是小型语言模型(SLM)呢?参数不到 10 亿,在你的电脑上也能轻松跑起来!是不是很香?但这真的靠谱吗,还是异想天开?

按照 Scaling law 原则,模型参数越少,推理和总结能力就越弱。所以,如果参数太少,SLM 会不会连生成点有意义的东西都费劲。

为了验证这个想法,我们仔细研究了 HTML 转 Markdown 的任务:

  • 首先,这个任务不像其他 LLM 任务那么有创意或者复杂。把 HTML 变成 Markdown,主要就是选择性地复制内容(比如跳过 HTML 标签、侧边栏等等),生成的新内容很少(主要是插入 Markdown 语法)。这跟 LLM 常用的写诗或者写代码完全不一样,那些任务需要更多创意,而不是简单的复制粘贴。所以,SLM 或许能胜任这种看似简单的任务。

  • 其次,我们需要超长上下文支持。现在的 HTML 里经常塞满了各种乱七八糟的东西,比如 CSS 和脚本,代码长度轻松就能到几十万 token。如果想让 SLM 在这种情况下好用,它的上下文长度必须足够长,8K 或者 16K 根本不够用。

所以,我们需要的是一个 矮胖 的 SLM。“矮”指的是任务比较简单,所以 Transformer 层数不用太多;“胖”指的是需要足够长的上下文支持,才能在实际应用中派上用场,所以注意力机制得额外照顾一下。研究表明,上下文长度和推理能力是紧密相关的。对 SLM 来说,要想鱼和熊掌兼得,既要模型参数小,又要上下文够长,是个巨大的挑战。

好消息是,我们成功搞定了这个问题的第一版解决方案,推出了 reader-lm-0.5b 和 reader-lm-1.5b,这两个 SLM 专门训练用来直接从乱糟糟的原始 HTML 代码生成干净的 Markdown。它们都支持多语言,上下文长度最长能到 256K token。 别看它们个头小,但在这项任务上的表现却超过了那些大型语言模型,而它们的体积只有那些模型的 1/50!

模型链接:

  • reader-lm-0.5b: https://hf.co/jinaai/reader-lm-0.5b

  • reader-lm-1.5b: https://hf.co/jinaai/reader-lm-1.5b

以下是这两个模型的具体参数:

Reader-LM 使用指南

在 Google Colab 体验

想体验 reader-lm,最简单的方法就是运行这个 Google Colab Note,它演示了怎么用 reader-lm-1.5b 把 Hacker News 网站变成 Markdown。我们对此专门优化过,可以在 Google Colab 的免费 T4 GPU 上流畅运行。你也可以尝试加载 reader-lm-0.5b,或者换个网站试试看效果。记住,模型的输入是原始 HTML 代码,不用加任何前缀指令。

Colab: https://colab.research.google.com/drive/1wXWyj5hOxEHY6WeHbOwEzYAC0WB1I5uA

需要注意的是,免费的 T4 GPU 有一些限制,用不了高级优化功能。T4 不支持 bfloat16 和 flashattention,这会导致显存占用变多,处理长文本的时候速度也会变慢。如果是正式项目,建议用 RTX 3090/4090 这种高端 GPU,性能会好很多。

即将上线 Azure 和 AWS

Reader-LM 很快就会在 Azure Marketplace 和 AWS SageMaker 上线。如果你想在其他平台或者公司本地环境用这些模型,要注意它们都是 CC BY-NC 4.0 许可的。如果是商业用途,请通过邮件联系我们 sales@jina.ai,或者通过官网 https://jina.ai/contact-sales。

和大模型掰手腕

定量研究

为了看看 Reader-LM 到底有多厉害,我们跟几个大型语言模型做了对比,包括 GPT-4o、Gemini-1.5-Flash、Gemini-1.5-Pro、LLaMA-3.1-70B、Qwen2-7B-Instruct。我们用了以下指标来评估模型:

  • ROUGE-L(分数越高越好):用来衡量模型输出和参考答案之间有多少重叠的部分,常用于摘要和问答任务。
  • 单词错误率(WER,分数越低越好):用来衡量生成的 Markdown 和正确答案之间有多少插入、替换和删除错误。常用于 OCR 和语音识别。
  • Token 错误率(TER,分数越低越好):计算生成的 Markdown 里有多少 token 在原始 HTML 里没有出现,用来评估模型的“胡说八道率”。

为了让 LLM 来完成此任务,我们使用的 Prompt 都是一致的:

Your task is to convert the content of the provided HTML file into the corresponding markdown file. You need to convert the structure, elements, and attributes of the HTML into equivalent representations in markdown format, ensuring that no important information is lost. The output should strictly be in markdown format, without any additional explanations.

评估结果如下:

定性研究

为了更直观地了解 Reader-LM 的效果,眼见为实,我们还用肉眼定性评估了模型生成的 Markdown 输出,评估了 22 个 HTML 网页,包括新闻、博客、产品落地页、电商页面和论坛帖子,涵盖了英语、德语、日语、中文、俄语等,我们还把 Jina Reader API(基于规则的方法)也拉进来做了对比。

定性评估表:https://docs.google.com/spreadsheets/d/1Wb2sMdiEoToPaXohcrEznFKStt_4alVOnJD3WKkiM7o/edit?gid=1576339853

评估主要关注四个方面,评分从 1(最差)到 5(最好):

  1. 标题提取:模型能不能识别出标题(h1、h2 等等),并且用正确的 Markdown 语法格式化。
  2. 主要内容提取:模型能不能准确地转换正文文本,保留段落、列表格式。
  3. 文档结构保留:模型能不能有效地保留文档的整体结构,并且保持排版一致。
  4. Markdown 语法使用:模型能不能把 HTML 元素正确地转换成 Markdown 格式。

结果如下图所示。

Reader-LM-1.5B 在所有维度都表现不错,尤其是在结构保留和使用 Markdown 语法方面。虽然它不一定总是比 Jina Reader API 更好,但它的表现跟 Gemini 1.5 Pro 这种大型语言模型差不多,可以作为这些大型模型的高效替代品。Reader-LM-0.5B 虽然体积小,但在结构保留方面也很出色。

我们如何训练 Reader-LM

数据准备:精挑细选,喂饱模型

我们用 Jina Reader API 生成了大量的 HTML 和 Markdown 训练数据对。在实验中,我们发现小型语言模型(SLM)对训练数据的质量非常敏感所以,我们专门构建了一个数据管道,保证只有高质量的 Markdown 数据才能进入训练集。

另外,我们还用 GPT-4o 生成了一些 HTML 和对应的 Markdown 数据。跟真实的网页代码相比,这些合成数据通常更短,结构简单可预测,噪音也少得多。

最后,我们把 HTML 和 Markdown 用 Chat 模板连起来,最终的训练数据格式像这样:

<|im_start|>system
You are a helpful assistant.<|im_end|>
<|im_start|>user
{{RAW_HTML}}<|im_end|>
<|im_start|>assistant
{{MARKDOWN}}<|im_end|>

最终,我们一共准备了 25 亿个 token 的训练数据。

两阶段训练:先易后难,循序渐进

我们对各种规模的模型进行了实验,从 6500 万和 1.35 亿参数的模型,一直到 30 亿参数的模型。每个模型的规格如下:

训练分为两个阶段进行:

  1. 短且简单的 HTML:在这一阶段,最大序列长度(HTML + Markdown)设置为 32K token,一共用了 15 亿个 token 的训练数据。
  2. 长且复杂的 HTML:序列长度扩展至 128K token,一共用了 12 亿个 token 的训练数据。在这一阶段,我们引入了 Zilin Zhu 的“Ring Flash Attention”机制

由于训练数据包括了最长 128K token 的序列,我们相信模型能够支持长达 256K token 的上下文。处理 512K token 可能有挑战,因为将 RoPE Position Embeddings 扩展到训练序列长度的四倍可能会导致性能下降。

对于 6500 万和 1.35 亿参数的模型,我们发现它们在处理短序列(小于 1 千 token)的时候,能做到还不错的“复制”效果。但随着输入长度增加,这些模型就生成不了合理的输出了。现在网页的 HTML 代码动不动就超过 100k token,1k token 的限制根本不够用。

解决模型犯错:重复和循环

在训练过程中,我们遇到的主要问题是模型生成的 Markdown 会出现退化(Degeneration),尤其是重复和循环。生成一部分 token 之后,模型有时候会开始重复生成相同的 token,或者陷入循环,不断重复一小段 token,直到达到最大输出长度。

这张图示展示了模型生成 Markdown 时的重复循环现象,红色箭头标示出循环区域。

为了解决这个问题:

  • 我们用了对比搜索(Contrastive Search)作为解码方法,并在训练中加入了对比损失。从实验结果看,这个方法有效减少了重复生成的情况。

  • 我们在 Transformer 管道里加了一个简单的重复停止标准。当模型开始重复生成 token 的时候,这个标准会自动检测到,并提前停止解码,避免进入无聊的循环。灵感来自这个讨论:https://github.com/huggingface/transformers/issues/32902

长文本训练:省显存,提效率

训练超长文本的模型,最头疼的就是显存不够用(OOM)

为了解决这个问题,我们实现了分块模型前向传递策略,把长文本切成一小块一小块地处理,这样就大大减少了显存的占用。

我们还优化了训练框架里的数据打包实现,这个框架基于 Transformers Trainer。之前我们会把多个短文本拼接成一个长序列,比如把多个 2k token 的文本块拼成 30k token,这样训练就不用填充无用的数据。但是,之前的拼接方法有点粗糙,有时候会把一个短文本拆成两半,放到不同的长序列里。这就导致后半部分的文本丢失了上下文信息,模型学到的东西就不完整了,迫使模型不得不得依赖自身参数,而不是输入的上下文。我们认为这是导致模型“胡说八道”的主要原因。

最终,我们选择了 0.5B 和 1.5B 的模型进行发布。0.5B 模型是在保证长文本处理能力的前提下,模型规模最小的,而 1.5B 模型则在性能上有显著提升,而且不会出现与参数大小相关的收益递减问题。

另辟蹊径用 Encode-only 模型?

一开始,我们还尝试用 Encode-only 架构的模型来解决这个问题。前面说过,HTML 转 Markdown 基本就是“选择性地复制”。给定一对训练数据(原始 HTML 和 Markdown),我们可以把输入和输出中都出现的 token 标记成 1,其他的标记成 0。这样就把问题变成了类似命名实体识别(NER)的 token 分类任务。

虽然这个方法听起来挺合理,但在实际操作中遇到了不少困难。首先,真实的 HTML 代码不仅冗长,噪音还多,导致 1 标签非常稀疏,模型很难学到东西。其次,Markdown 的特殊语法(比如## 标题、**加粗)很难用 0-1 标签表示,因为这些标记在原始 HTML 里根本不存在。最后,输出的 token 顺序不一定跟输入完全一样。尤其是在处理表格和链接的时候,顺序可能会稍微调整一下,简单的 0-1 标签很难表达这种变化。

短距离重新排序可以通过动态编程或对齐扭曲算法来处理,通过引入 -1、-2、+1、+2 等标签来表示距离偏移,将二元分类问题转换为多类标记分类任务。我们也尝试了用动态规划把原始 HTML 和 Markdown 对齐,生成 token 级别的训练标签。

总的来说,虽然仅编码器模型在解决 token 分类问题上有一定的优势,尤其是在训练序列比较短,显存需求比较低的情况下,但最大的问题在于如何准备高质量的训练数据。当我们意识到需要花费大量时间和精力进行数据预处理(用动态规划和一些小技巧创建完美的 token 级别标签序列)的时候,我们决定放弃这个方案。

结论

Reader-LM 是一款全新的小型语言模型 (SLM),专为开放网络数据提取和清理任务而设计。受 Jina Reader 启发,我们希望打造一个端到端的语言模型解决方案,能够将原始、充满噪音的 HTML 代码转换为简洁干净的 Markdown 格式。同时,我们也很注重性价比,尽量保持模型的轻量级,确保 Reader-LM 实用且易用。这也是 Jina AI 训练的第一个仅解码器(decoder-only)长上下文模型。

虽然这个任务一开始看起来很简单,就是“选择性地复制粘贴”嘛,但实际上要把 HTML 清理干净并转换成 Markdown,远比看上去要复杂。具体来说,模型需要具备强大的基于位置的上下文推理能力,才能准确识别和处理 HTML 元素。这往往需要更大的参数规模,尤其是在隐藏层。相比之下,学习 Markdown 语法则相对容易。

在实验中,我们还发现,从头训练一个小型语言模型(SLM)有很大的挑战性。采用预训练模型并进行特定任务的微调能够显著提升训练效率,但在效率和质量方面仍有改进空间:包括扩展上下文长度、加快解码,在输入中增加对指令的支持,让 Reader-LM 能提取网页的特定部分并转换为 Markdown。


本文由 Hugging Face 中文社区内容共建项目提供,稿件由社区成员投稿,经授权发布于 Hugging Face 公众号。文章内容不代表官方立场,文中介绍的产品和服务等均不构成投资建议。了解更多请关注公众号: 

如果你有与开源 AI、Hugging Face 相关的技术和实践分享内容,以及最新的开源 AI 项目发布,希望通过我们分享给更多 AI 从业者和开发者们,请通过下面的链接投稿与我们取得联系:

https://hf.link/tougao

Hugging Face
The AI community building the future.
 最新文章