[Bug]: TokenChunker cuts multi-token characters at chunk boundaries, leaving U+FFFD in text units
维护者通常 5 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 3/5
- 预计耗时
- 1-2 天
- 新手友好度
- 67/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 技术栈
- python
调研方向
Read packages/graphrag-chunking/graphrag_chunking/token_chunker.py, especially split_text_on_tokens, and examine how its token windows are decoded. Add regression tests for the provided multilingual example, checking that chunks contain no unexpected U+FFFD and join back to the input when overlap is zero. The issue suggests keeping the existing encode/decode interface; done means boundaries preserve characters.
由索引模型根据 Issue 内容生成。
描述
Do you need to file an issue?
- I have searched the existing issues and this bug is not already filed.
- My model is hosted on OpenAI or Azure. If not, please look at the "model providers" issue and don't file a new one here. (Not applicable: the bug is in chunking, before any model call.)
- I believe this is a legitimate bug, not just a question. If this is a question, please use the Discussions area.
Describe the bug
split_text_on_tokens in packages/graphrag-chunking/graphrag_chunking/token_chunker.py decodes every window of token ids on its own:
chunk_text = decode(list(chunk_tokens))
When a character is encoded as more than one token, a window boundary can fall inside it. tiktoken's decode turns the incomplete UTF-8 sequence into U+FFFD, so the chunk ends with � and the next one starts with �. With overlap: 0 that character is in no chunk at all. With an overlap it survives in the overlapping chunk, but every affected text unit still carries one or two � into extraction and embedding.
With the default o200k_base this hits emoji, rarer Han characters, Tibetan and Amharic, among others. In short samples, 5 of the 14 token boundaries in a string of ten emoji fall inside a character, and 20 of the 42 in a Tibetan phrase. With cl100k_base, common Chinese characters are affected too. That is what #596 ran into ("官方用的分块是先把文档token化,按照token数进行切分,对于中文来说容易出现乱码"). That issue was closed on the extraction question, and the chunker is unchanged since.
Steps to reproduce
graphrag-chunking 3.2.0, tiktoken 0.14:
import tiktoken
from graphrag_chunking.token_chunker import split_text_on_tokens
enc = tiktoken.get_encoding("o200k_base")
text = "关系。龘靐齉爩 是很少见的汉字。" * 3
chunks = split_text_on_tokens(text, chunk_size=7, chunk_overlap=0, encode=enc.encode, decode=enc.decode)
print([c for c in chunks if "�" in c])
print("".join(chunks) == text)
['关系。龘靐�', '�爩 是很少见', '的汉字。关系。�', '�靐齉爩']
False
One 龘 and one 齉 are missing from the joined chunks.
Expected Behavior
A chunk boundary falls between characters, so no chunk contains U+FFFD unless the input does, and with overlap: 0 the chunks join back into the input.
GraphRAG Config Used
chunking:
type: tokens
size: 1200
overlap: 100
encoding_model: o200k_base
(the defaults; the repro above calls the function directly with a small size)
Logs and screenshots
No response
Additional Information
- GraphRAG Version: graphrag-chunking 3.2.0 (main has the same
split_text_on_tokens) - Operating System: macOS
- Python Version: 3.12
- Related Issues: #596
A fix can stay inside split_text_on_tokens and keep its encode/decode interface: before cutting at token index b, check that the cut does not split a character, for example decode(tokens[b-4:b]) + decode(tokens[b:b+4]) == decode(tokens[b-4:b+4]) (a UTF-8 character spans at most four bytes), and move b back one token while it does. I can open a PR with that and a test if the approach is fine with you.
- 主要语言
- Python
- 星标
- 36.6k
- 派生
- 3.9k
- 平均合并
- 4 天 11 小时
- 30 天内合并 PR
- 1
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
microsoft/graphrag 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 74/100
microsoft/graphrag#2626 · 1 条评论 ·
维护者通常 5 天内回复
-
[Bug]: response_format_json_object=True is silently dropped, so JSON mode never reaches the model未关闭bug triage
难度 2/5 1-3 小时 新手友好度 72/100
microsoft/graphrag#2625 · 1 条评论 ·
维护者通常 5 天内回复
-
难度 1/5 1 小时以内 新手友好度 95/100
维护者通常 5 天内回复
-
[Bug]: JsonCache.get() crashes with unhandled AttributeError on non-dict or invalid envelope JSON payloads可能重新可做 关联的 PR 已关闭且未合并。 未关闭
难度 2/5 1-3 小时 新手友好度 82/100
microsoft/graphrag#2614 · 2 条评论 ·
维护者通常 5 天内回复
-
难度 2/5 1-3 小时 新手友好度 85/100
microsoft/graphrag#2594 · 1 条评论 ·
维护者通常 5 天内回复
查看 microsoft/graphrag 的全部 Issue
相似的 Issue
-
documentation good first issue
难度 2/5 1-3 小时 新手友好度 88/100
JheysonJhordyHuarauyaRiquelme/sprocguard#18 ·
维护者通常 1 天内回复
-
enhancement good first issue help wanted
难度 2/5 1-3 小时 新手友好度 80/100
dlq/synthpopcan#59 ·
维护者通常 2 天内回复
-
难度 2/5 1-3 小时 新手友好度 72/100
mdn/translated-content#40220 ·
维护者通常 4 天内回复
-
enhancement
难度 2/5 1-3 小时 新手友好度 84/100
ETSInitiative/PETSIRD#243 ·
维护者通常 1 天内回复
-
deferred p2
难度 2/5 1-3 小时 新手友好度 70/100
cuadrao-ai/argus#2160 ·
维护者通常 1 天内回复