最近在搭一个基于RAG的文档问答系统,主要处理公司内部的PDF报告。目前用的langchain+chroma+openai embedding,分块策略是recursive split。但发现一个问题:只要文档里有表格或者图表,问答的时候模型就经常说“找不到相关信息”,明明表格里就是答案所在。感觉是分块时把表格内容切碎了,或者embedding时没有保留结构信息。请教各位大佬,有没有处理PDF中表格和图表的成熟思路?比如用多模态模型先把图转成文本描述,或者用OCR工具单独提取?希望不增加太多推理延迟。
RAG做PDF问答时,表格和图表内容总丢,有什么好办法?
全部回复
共 125 条我试过类似的情况,recursive split对表格确实不友好,切成小块后语义全散了。你可以试试unstructured库或者table-transformer这类专门抽表结构的工具,把表格转成markdown格式再喂给embedding模型,效果会好不少。图表的话,如果预算允许,加个MiniGPT-4或者GPT-4V做离线描述生成,把描述文本和原图表一起入库,推理时只走文本检索,延迟基本没影响。另外,检索后可以加一步rerank,让LLM优先看包含表格的关键块,不然还是容易漏。
表格被recursive split切碎这个问题太典型了,我试过给表格加特殊分隔符再合并相邻块,能稍微好点但治标不治本。后来干脆把表格区域单独识别出来,转成markdown格式塞进上下文,比纯文本强不少。图表的话,如果你不想上多模态模型,可以试试用OCR工具把图里的文字抽出来加上图的标题和页码,做成一个“伪文本块”,至少能回答“图里说了什么”这种问题。不过延迟确实是个坎,建议先离线把图表预处理存好,别让用户请求时现算。
试试unstructured库先按版面拆表格,再单独走OCR转html,比无脑切块强不少。
试试把表格转成markdown再切块,或者用unstructured单独抽表,效果比纯文本强不少。
我最近也踩过这个坑,recursive split对表格基本就是灾难,行被切散后语义全没了。后来我把表格区域单独检测出来,用pandas转成markdown格式再embedding,效果好了不少。图表的话确实得走多模态,但不用全量上,可以只在检索到相关图片时再调一下视觉模型做描述,延迟能接受。另外建议试试unstructured库,它对PDF里的表格识别比langchain默认的loader强很多。
我最近也踩过这个坑,recursive split对表格真的不友好,切成小块后表头跟数据就分家了。我现在是先用unstructured库单独把表格区域识别出来,转成markdown格式再喂给embedding,效果比纯文本好不少。图表的话建议用多模态模型离线生成描述存成索引,别在线调用,延迟能控制在可接受范围。你们有试过把表格转成图片再走VLM吗?
我之前也踩过这个坑,recursive split对表格就是灾难,行被切得七零八落。我后来是先用camelot或pdfplumber单独把表格抽出来转成markdown格式,再跟上下文拼一起喂给embedding,效果好了不少。图表的话,纯文本路子确实有限,要是能接受一点延迟,可以试试用vision模型跑一遍生成描述,然后当普通文本块存进去,比直接丢OCR强。另外你还可以考虑把表格区域单独建个索引,问答时先判断问题是不是偏向数值类,再决定去哪个库检索,这样能省点时间。
试试把表格转成markdown再入库,检索效果比纯文本好不少,图表直接用多模态模型描述下就行。
可以试试把表格区域单独抽出来转成markdown或key-value文本再喂给embedding,我这么干过,效果立竿见影。
多模态描述图表确实有用,但延迟会涨不少,建议先做个缓存,只对首次遇到的图走一遍。
试试先把表格单独抽出来转成图片,用多模态模型生成描述再塞回分块,效果比硬切强很多。
试试表格先转成markdown再切块,图表用多模态模型生成描述文本挂到原位置,延迟也就多个一两秒。
说实话你这个问题太典型了,recursive split对表格基本就是灾难,它按字符长度硬切,表头和数据行很容易被拆到不同chunk里,语义就断了。我这边之前也是被这个坑了很久,后来改成了基于文档结构的切分,比如用unstructured库先把PDF解析成markdown格式,表格会保留成管道符分隔的文本,这样embedding至少能捕捉到行列关系,比纯文本切碎效果好很多。但图表光靠这个还是不行,因为图表的信息本身是视觉化的,你如果不想上多模态,可以先用OCR或者专门的图表解析工具把图里的趋势、数值抽出来存成描述性文本,再跟原图位置关联起来。延迟这块其实不用太担心,离线预处理阶段做一次就够了,问答时候还是走纯文本检索,关键是要把提取出的描述跟原始图片做个映射,必要时返回原图给前端展示。另外建议你试试给每个chunk加metadata,比如标记它是表格还是正文,检索的时候可以按权重调,避免正文chunk把表格chunk挤掉。如果报告里表格特别多,也可以考虑单独建一个表格索引,用text-to-sql那套思路去查,准确率会高不少。
这问题太典型了,recursive split对表格就是灾难,结构全打散了。我之前试过把表格区域单独识别出来,用unstructured库按标题和表格边界切块,然后每个表格单独成一个chunk,问答准确率立刻上来了。图表的话,如果不想上多模态,可以先用OCR把图里的文字提出来,配上图上标题做成文本块,虽然丢点视觉信息,但对付“数据是多少”这类问题够用了。延迟这块你不用担心,OCR和表格识别都是离线预处理,在线检索没啥额外开销。
试试把表格转成markdown再切块,检索效果比纯文本好不少,图表还是得靠多模态描述。
试试把表格转成markdown再切块,图表用多模态模型描述后单独存,效果能好不少。
表格这块我之前也踩过坑,recursive split确实会把表头和单元格拆散,embedding出来全是碎片。后来改成先单独检测表格区域,用camelot或者pdfplumber按表格结构转成markdown,再作为一个整体块塞进去,召回率明显上来了。图表的话如果你不想上多模态,可以试试用OCR工具把图里的关键数字和标题抽出来拼成一段描述,虽然会丢点细节但至少能答个大概。另外想问你现在的分块大小和重叠是多少,有时候调大块尺寸反而比转格式更管用。
我之前也踩过这个坑,recursive split对表格基本就是灾难,行被拆开后语义全断了。后来我改成先跑一遍pdfplumber把表格区域单独拎出来,转成markdown或者HTML格式再喂给embedding模型,效果好了不少。图表的话确实得走多模态,但不用每次都调大模型,可以先用ocr把图里的文字抽出来,配合caption一起存成文本块,这样延迟增加得有限。另外你试试把表格相关的query单独路由到一个结构化检索逻辑里,别跟普通文本混在一起,命中率会高很多。
试试unstructured库做分区解析,表格单独走pandas处理后再embed,比纯recursive靠谱很多。
试试把表格转成markdown再切块,比纯文本保留结构,能救回来不少。
之前用unstructured专门抽表格,配GPT-4V生成描述,准确率提了一截,延迟也还好。
我之前也踩过这个坑,recursive split对表格就是灾难,后来把表格单独用unstructured库抽出来转成markdown格式再塞进上下文,效果好了不少。图表的话确实得靠多模态,不过建议别在pipeline里直接调视觉模型,太慢,可以离线批量把图描述好存成metadata,问答时只检索描述文本。另外你试试把表格转成html或者csv再embedding,结构信息保留得比纯文本好,召回率能提一截。