jina 出了 ReaderLM v2 版本,这个版本的 ReaderLM 在处理文本数据时更加高效和准确。 之前简单测试了下 v1, 结论是:
幻觉严重, 尤其特别喜欢造 url
很容易触发无限生成 比如 example1 example2…. 一直生成下去
第一眼就是不可用就没继续了。 这次 v2 来了,测试了一下,幻觉问题好了很多,无限生成测试了几个也没遇到,但最为一个 html 转 markdown 的工具还是不够稳定。 这里的稳定性主要是指,与传统的基于语法树解析的工具相比,它在处理速度和结构识别的准确性上还有差距。他的确能生成不错的 markdown,但是很容易被正确结构但是内容文本里有特殊构造的/或者有一些语法错误的 html 页面所影响。
注意:这个博客里的测试只是为了列出 v2 的一些问题,针对问题进行特殊构造的测试,实际网页可能也遇不到文中提到的问题,具体以实际场景为准了。 顺道一提,这个模型是以 CC 协议发布的,所以商用场景需要遵守相关协议。
测试 测试直接使用 hf 页面上的colab 环境,改一下 html 就行,用我们自己构造的 html。
结构丢失/错乱 构造了一个嵌套比较多的 html 结构 查看最后结果 测试 html:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 <!DOCTYPE html > <html lang ="zh-CN" > <head > <meta charset ="UTF-8" /> <meta name ="viewport" content ="width=device-width, initial-scale=1.0" /> <title > 嵌套层级示例</title > </head > <body > <header > <h1 > 嵌套层级示例</h1 > </header > <div id ="main-content" > <div class ="section" > <h2 > 第一部分</h2 > <div class ="subsection" > <p > 这是一个段落,嵌套在第一部分的子部分中。</p > <div class ="nested-div" > <p > 这是一个更深层级的段落,嵌套在子部分的 div 中。</p > <div class ="deeply-nested" > <p > 这是一个更深层级的段落,嵌套在更深层级的 div 中。</p > <div class ="very-deeply-nested" > <p > 这是一个非常深层级的段落,嵌套在非常深层级的 div 中。</p > </div > </div > </div > </div > </div > <div class ="section" > <h2 > 第二部分</h2 > <div class ="subsection" > <p > 这是第二部分的第一个段落。</p > <div class ="nested-div" > <p > 这是嵌套在第二部分的 div 中的段落。</p > <div class ="deeply-nested" > <p > 这是更深层级的段落。</p > <div class ="very-deeply-nested" > <p > 这是非常深层级的段落。</p > <div class ="extremely-deeply-nested" > <p > 这是极其深层级的段落。</p > </div > </div > </div > </div > </div > <div class ="subsection" > <p > 这是第二部分的第二个子部分。</p > <div class ="nested-div" > <p > 这是另一个嵌套的段落。</p > <div class ="deeply-nested" > <p > 这是更深层级的段落。</p > </div > </div > </div > </div > <div class ="section" > <h2 > 第三部分</h2 > <div class ="subsection" > <p > 这是第三部分的段落。</p > <div class ="nested-div" > <p > 这是嵌套在第三部分的 div 中的段落。</p > <div class ="deeply-nested" > <p > 这是更深层级的段落。</p > <div class ="very-deeply-nested" > <p > 这是非常深层级的段落。</p > <div class ="extremely-deeply-nested" > <p > 这是极其深层级的段落。</p > <div class ="ultra-deeply-nested" > <p > 这是超深层级的段落。</p > </div > </div > </div > </div > </div > </div > </div > </div > <footer > <p > © 2023 示例公司. 保留所有权利.</p > </footer > </body > </html >
结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 # 嵌套层级示例 ## 第一部分 这是一个段落,嵌套在第一部分的子部分中。 ### 第一个子部分 这是一个更深层级的段落,嵌套在子部分的 div 中。 #### 第二个子部分 这是一个更深层级的段落,嵌套在更深层级的 div 中。 ##### 更深层级的段落 这是一个非常深层级的段落,嵌套在非常深层级的 div 中。 ## 第二部分 ### 第二部分的第一个段落 这是第二部分的第一个段落。 #### 第二部分的 div 中的段落 这是一个嵌套在第二部分的 div 中的段落。 ##### 更深层级的段落 这是一个更深层级的段落。 ###### 第三部分的段落 这是第三部分的段落。 #### 第二部分的 div 中的段落 这是嵌套在第三部分的 div 中的段落。 ##### 更深层级的段落 这是更深层级的段落。 ###### 第二部分的子部分 这是另一个嵌套的段落。 ##### 更深层级的段落 这是更深层级的段落。 ## 第三部分 ### 第三部分的段落 这是第三部分的段落。 #### 第二部分的 div 中的段落 这是嵌套在第三部分的 div 中的段落。 ##### 更深层级的段落 这是更深层级的段落。 ###### 第二部分的子部分 这是另一个嵌套的段落。 ##### 更深层级的段落 这是第二部分的子部分。 ##### 第三部分的段落 这是嵌套在第三部分的 div 中的段落。 ##### 更深层级的段落 这是更深层级的段落。 ###### 第二部分的子部分 这是另一个嵌套的段落。 ##### 更深层级的段落 这是第二部分的子部分。
在这个测试中,我构造了一个多层嵌套的 HTML 结构,目的是验证 ReaderLM v2 在处理复杂嵌套时的表现。 结果显示,模型在转换过程中丢失了部分内容,并且层级结构出现了错乱。例如,原本的“第一部分”、“第二部分”和“第三部分”在 Markdown 中被错误地合并或拆分,导致语义不连贯。这表明模型在处理深度嵌套的 HTML 结构时,可能无法准确识别和保留原有的层级关系,从而影响输出结果的可读性和准确性。
被符号干扰 产生幻觉 测试:
1 2 3 4 <div > 测试1+1= <div > '"这是一句带各种标点,.。的话</div > </div >
返回:
1 2 3 测试 1+1= "这是一句带各种标点,.。的话"
这个测试旨在验证模型对特殊符号(如引号、标点符号等)的处理能力。我们构造了一个包含多种符号的 HTML 片段,结果显示模型在转换过程中对符号的处理不一致,甚至产生了“幻觉”(即输出与输入不符)。例如,输入中的单引号和双引号在输出中被错误地调整或省略,导致语义发生变化。这表明模型在处理符号时可能存在一定的局限性,尤其是在符号与上下文结合紧密的情况下,容易产生错误。
注释干扰 测试:
返回:
1 测试 1+1='<!-- 这句话不应该出现 -->2<!-- 连续注释 -->'
在这个测试中,我们构造了一个包含 HTML 注释的片段,目的是验证模型是否能正确处理注释内容。结果显示,模型在注释前后存在单引号的情况下,未能正确忽略注释内容,导致注释被保留在输出中。这表明模型在处理注释时,可能会受到周围符号(如引号)的干扰,从而无法完全过滤掉注释内容。这种问题在实际应用中可能会导致不必要的噪音,影响输出结果的纯净度。
转义问题 测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 <h1 > 转义字符测试</h1 > <p > 这是一个包含各种转义字符的段落:</p > <ul > <li > 小于号:< </li > <li > 大于号:> </li > <li > 和号:& </li > <li > 双引号:" </li > <li > 单引号:' </li > <li > 版权符号:© </li > <li > 注册商标符号:® </li > <li > 商标符号:™ </li > <li > 欧元符号:€ </li > <li > 英镑符号:£ </li > <li > 日元符号:¥ </li > <li > 分符号:¢ </li > <li > 章节符号:§ </li > <li > 段落符号:¶ </li > <li > 中间点:· </li > <li > 短破折号:– </li > <li > 长破折号:— </li > </ul > <p > 这是一个包含特殊字符的代码块:</p > <pre > <code > def escape_example(): print("< > & " ' © ® ™ € £ ¥ ¢ § ¶ · – — ") </code > </pre > <p > 这是一个包含转义字符的链接:<a href ="https://example.com?q=test& lang=en" > 点击这里</a > </p >
结果:
转义字符测试
------------
这是一个包含各种转义字符的段落:
- 小于号:<
- 大于号:>
- 和号:&
- 双引号:"
- 单引号:'
- 版权符号:copy
- 注册商标符号:reg
- 商标符号:trade
- 欧元符号:euro
- 英镑符号:pound
- 日元符号:yen
- 分符号:cent
- 章节符号:sect
- 段落符号:para
- 中间点:middot
- 短破折号:–
- 长破折号:–
这是一个包含特殊字符的代码块:
1 2 def escape_example (): print ("< > & \" ' copy reg trade euro pound yen cent sect para middot -- —" )
这是一个包含转义字符的链接:[点击这里](https://example.com?q=test&lang=en)
```
emmm 博客显示原文有点问题 这里截个图:
这个测试重点验证模型对 HTML 转义字符的处理能力。我们构造了一个包含多种转义字符(如 <
、>
、&
等)的 HTML 片段,结果显示模型在转换过程中未能正确还原所有转义字符,甚至出现了错误转换(如将 ©
转换为 copy)。此外,模型还错误地处理了 <pre>
标签内的内容,导致代码块中的转义字符也被错误地转换。这表明模型在处理转义字符时存在明显的不足,尤其是在需要保留原始格式的场景下,可能会严重影响输出结果的质量。
总结 LLM 在处理许多语言相关任务时表现出色,尤其是在自然语言生成、翻译、摘要等领域,效果往往优于传统方法。
然而,当涉及到 HTML 转 Markdown 这种任务时,当前的 Jina ReaderLM v2 仍然存在不少问题。这些问题不仅体现在结构丢失、符号干扰、注释处理等方面,还表现在对 HTML 和 Markdown 这种相对宽松、自由的结构转换上。
相比于 JSON 等严格结构化的数据转换,HTML 和 Markdown 的灵活性使得转换过程更加复杂,容易受到各种特殊符号、嵌套结构、注释等干扰,导致输出结果不稳定。因此,尽管 ReaderLM v2 在幻觉问题和无限生成问题上有所改进,但在实际应用中,尤其是对结构要求较高的场景下,仍需进一步优化和提升。
还测试了一些正常的页面,比如他例子里给的 yc 官网。对这些页面进行转换后,结果都比较正常,但是这速度是有点慢了,yc 官网不管用 colab(免费版)还是 jina 的 api(也是免费版)都需要将近 1 分钟才能返回,可能是免费版在排队吧,不过如果速度就是这么慢的话,可能只适合小量处理,这个等大佬做了量化之后再看看效果吧。
参考资料 jinaai/ReaderLM-v2
ReaderLM v2:用于 HTML 转 Markdown 和 JSON 的前沿小型语言模型