分块 (Chunk)

将大型数据或文本分割成便于处理的小单元。广泛应用于 AI 的令牌数限制应对、流式传输、文件传输等场景。

分块 (chunk) 是将大型数据按照一定大小或有意义的单位进行分割后得到的片段。这个源自英语"块"的词已成为通用技术术语。在文本处理、网络通信和 AI 领域中,chunk 各有不同的含义,但"将大的东西分成易于处理的单位"这一本质是共通的。

在 AI、LLM (大语言模型) 领域,分块 (chunking) 是指把文本分割成能装进模型上下文窗口的大小的处理。这个上限因模型而异,从数万令牌规模到百万令牌规模都有,而且每次世代更替都会变化,因此不要去记住某个特定模型的数值,而应把它当作"在所用 API 的文档中确认的值"来处理,这样才安全。即使长度在上限之内,输入变长也会让费用和响应时间随令牌数而增加。通常的做法是分割成只把必要的部分递过去的形式,分别处理各个块之后再整合结果。

分块的质量取决于分割粒度和边界的选择。固定长度分块 (如每 1,000 个字符分割一次) 实现简单,但会在句子中间或段落中间截断,导致上下文丢失。语义分块则在段落、章节、标题等结构性边界处分割,使每个块成为语义完整的单元。也有设置重叠区域 (让前后的块共享一部分内容) 来减轻边界附近信息损失的做法。

HTTP 的分块传输编码 (Transfer-Encoding: chunked) 是在响应大小事先未知时,把数据分成小块逐步发送的机制。这是 HTTP/1.1 中定义的机制,在 HTTP/2 中不能使用。HTTP/2 用 DATA 帧这一自有的单位来分割并搬运数据,因此 chunked 本身的使用是被禁止的。对话型 AI 的响应一点一点出现在画面上这样的流式传输中,文本同样以很小的单位逐步发送,使用者无需等待生成完成即可开始阅读。实现上会使用 Server-Sent Events (text/event-stream) 这类逐步发送的形式,但无论哪一种,共通之处都在于放弃"等整体确定之后再发送",改为让片段流出。

在自然语言处理 (NLP) 中,分块是指从已标注词性的词序列中提取名词短语、动词短语等短语的处理。就是把"东京的大公园"识别为"东京的大公园"这一个名词短语,而不是"东京的""大的""公园"这样分开的处理。

决定块大小时,出发点是不要把字符数与令牌数混为一谈。即使字符数相同,令牌数也会因语言和字符种类而变化,因此只凭"切成多少字符"来决定的分割,对嵌入模型或模型侧的输入上限而言并不一定安全。分割的单位,用实际使用的 API 的令牌计数去确认才可靠。RAG (检索增强生成) 中会把文档分割成块存入向量数据库,但块太小会丢失前后的上下文,太大则会在一个块里混入多个话题,使检索的命中变钝。判断的大致标准有 3 条:是否在嵌入模型的输入上限之内,单独读一个块是否有足以回答一个问题的信息量,是否跨越了标题或段落这样的结构边界。把检索的单位与递给模型的单位分开来设计也很有效。用小块检索来缩小命中范围,递过去时再重新取回包含前后的更大范围,就能兼顾检索的精度与上下文的量。

分享这篇文章