深度拆解RAGFlow分片引擎之切片實現

上一篇深度拆解RAGFlow分片引擎!3大階段+視覺增強,全網最硬核架構解析 講了切片的整體流程,今天我們來拆下切片的實現。


我們在設置的時候,可以選擇切片方法。這個參數是parser_id

在創建知識庫的時候,選擇對應的切片方法以后,我們可以看到右側的切片介紹。

async def build_chunks(task, progress_callback):  # 根據配置獲取到切片實現(策略)chunker = FACTORY[task["parser_id"].lower()]
async with chunk_limiter:  cks = await trio.to_thread.run_sync(lambda: chunker.chunk(task["name"], binary=binary, from_page=task["from_page"],  to_page=task["to_page"], lang=task["language"], callback=progress_callback,  kb_id=task["kb_id"], parser_config=task["parser_config"], tenant_id=task["tenant_id"]))
  • 在上面的代碼里根據配置parser_idFACTORY中獲取到對應的實現文件
  • 注意chunker.chunk 調用對應實現文件中的chunk方法
from rag.app import laws, paper, presentation, manual, qa, table, book, resume, picture, naive, one, audio, email, tag
# 策略注冊(隱式接口)
FACTORY = {  "general": naive,   # 基礎文本處理器ParserType.NAIVE.value: naive,  ParserType.PAPER.value: paper,  # 學術論文處理器ParserType.BOOK.value: book,  ParserType.PRESENTATION.value: presentation,  ParserType.MANUAL.value: manual,  ParserType.LAWS.value: laws,  ParserType.QA.value: qa,  ParserType.TABLE.value: table,  # 表格專用處理器ParserType.RESUME.value: resume,  ParserType.PICTURE.value: picture,  ParserType.ONE.value: one,  ParserType.AUDIO.value: audio,  ParserType.EMAIL.value: email,  ParserType.KG.value: naive,  ParserType.TAG.value: tag  
}
  • FACTORY 對應的 實現,就是一個配置映射,根據前端的配置,然后映射到對應的方法
  • 我們可以看到對應的是從rag.app導入的

    看下代碼結構,都是對應的類文件。引入的類文件每個都有一個相同的chunk方法

這塊代碼就是一個典型的策略模式實現。

這里要吐槽下python的隱式接口,不是自己寫的代碼,一不小心得來回翻幾遍代碼。等我過兩天給它接口顯式實現。

整塊代碼邏輯如下:

策略工廠FACTORY
general/naive
paper
table
...
統一chunk方法接口
naive.py
paper.py
table.py
...其他處理器
分片請求
parser_id參數
執行具體分片邏輯
返回結構化分片數據

在上一篇中我們簡單的畫了下naive的處理流程,也就是前端選擇的general。我把流程復制過來。

DOCX
PDF
Excel
TXT/Code
Markdown
HTML/JSON
輸入文件
格式判斷
DOCX解析器
PDF解析器+布局識別
表格解析器
文本分割器
MD表格提取
結構化解析
原始分片生成
是否視覺增強?
視覺模型處理圖表
基礎分片處理
分片合并
Token化處理
輸出結構化分片

通用方法里,針對不同的文件類型,有對應的實現。

接下來,我們拆解幾個定向的分片實現。

Manual


前端顯示僅支持pdf,后端代碼支持pdfdocx。這塊代碼的整體處理邏輯如下

PDF
DOCX
文件輸入
文件類型判斷
PDF解析器
DOCX解析器
OCR+布局分析
表格識別
段落結構解析
表格HTML轉換
分塊處理
Token化輸出


manual中,并沒有抽取圖片,只抽取了表格,而且類似的代碼寫了兩遍。


我又對比了manualnaive下pdf的處理代碼。

  • manual 中注重的是文檔結構化,其他的并沒有增強
  • 反而在naive模式下,通過視覺模型對圖片進行了增強
  • 所以manual只適合沒有圖片的,有表格的pdf

laws

  • 法律文本的處理,在pdf上 處理上,唯一特殊的地方只有一個垂直合并

合并邏輯如下:

排序文本塊
遍歷相鄰塊
是否跨頁且無意義文本?
刪除當前塊
是否空文本塊?
計算合并特征
滿足禁止合并條件?
跳過合并
執行垂直合并

book

我們看了幾個,特殊場景的處理,其實最后都是通過pdf的差異化處理實現的。

resume 簡歷

  • 首先通過內部服務,會進行簡歷的處理,通過上下文,可以看到是對簡歷進行了結構化處理。

這個需要注意下,如果你源碼部署,一定要注意這個,否則就趟坑了。

然后通過結構化的關鍵詞,構建一個分片的數據結構。

qa

  
def rmPrefix(txt):  return re.sub(  r"^(問題|答案|回答|user|assistant|Q|A|Question|Answer|問|答)[\t:: ]+", "", txt.strip(), flags=re.IGNORECASE)  def beAdocPdf(d, q, a, eng, image, poss):  qprefix = "Question: " if eng else "問題:"  aprefix = "Answer: " if eng else "回答:"  d["content_with_weight"] = "\t".join(  [qprefix + rmPrefix(q), aprefix + rmPrefix(a)])  d["content_ltks"] = rag_tokenizer.tokenize(q)  d["content_sm_ltks"] = rag_tokenizer.fine_grained_tokenize(d["content_ltks"])  d["image"] = image  add_positions(d, poss)  return d  def beAdocDocx(d, q, a, eng, image, row_num=-1):  qprefix = "Question: " if eng else "問題:"  aprefix = "Answer: " if eng else "回答:"  d["content_with_weight"] = "\t".join(  [qprefix + rmPrefix(q), aprefix + rmPrefix(a)])  d["content_ltks"] = rag_tokenizer.tokenize(q)  d["content_sm_ltks"] = rag_tokenizer.fine_grained_tokenize(d["content_ltks"])  d["image"] = image  if row_num >= 0:  d["top_int"] = [row_num]  return d  def beAdoc(d, q, a, eng, row_num=-1):  qprefix = "Question: " if eng else "問題:"  aprefix = "Answer: " if eng else "回答:"  d["content_with_weight"] = "\t".join(  [qprefix + rmPrefix(q), aprefix + rmPrefix(a)])  d["content_ltks"] = rag_tokenizer.tokenize(q)  d["content_sm_ltks"] = rag_tokenizer.fine_grained_tokenize(d["content_ltks"])  if row_num >= 0:  d["top_int"] = [row_num]  return d

我們可以看到qa就是根據不同的結構解析出來問答對。

audio

def chunk(filename, binary, tenant_id, lang, callback=None, **kwargs):  doc = {  "docnm_kwd": filename,  "title_tks": rag_tokenizer.tokenize(re.sub(r"\.[a-zA-Z]+$", "", filename))  }  doc["title_sm_tks"] = rag_tokenizer.fine_grained_tokenize(doc["title_tks"])  # is it English  eng = lang.lower() == "english"  # is_english(sections)  try:  callback(0.1, "USE Sequence2Txt LLM to transcription the audio")  seq2txt_mdl = LLMBundle(tenant_id, LLMType.SPEECH2TEXT, lang=lang)  ans = seq2txt_mdl.transcription(binary)  callback(0.8, "Sequence2Txt LLM respond: %s ..." % ans[:32])  tokenize(doc, ans, eng)  return [doc]  except Exception as e:  callback(prog=-1, msg=str(e))  return []

這塊的代碼更簡單,直接通過語音模型轉成了文本,然后再進行處理。

picture

圖片的解析是使用OCR處理,所以識別到的是圖片上的文本內容。使用的是deepdoc之前測試,識別效果很一般。

圖片識別有兩種,一種是識別圖片中的文本內容,一種是通過圖片描述這個圖片是什么。我們可以通過擴展,ocr+圖片描述構建一個圖片檢索系統。

兩種實現方案:

  • 直接改這塊的源碼,添加圖片理解反推
  • 在外面將圖片反推后,構建圖片描述,后續我基于這個寫個案例

后記

通過代碼發現,專用處理有時候也蠻雞肋的,如果我們在外面將文檔都結構化了,很多通過一些分片策略,我們可以忽略一些專用類型。

底層的處理最后都是deepdoc中的幾個文件。后續會針對這個再做一些源碼分析。

rag玩的是對文檔的了解,怎么能拆解出合適的分片,這個是關鍵。

市面上應該有一些處理文檔的專有模型,到時候找下看看。

系列文章

uv配置環境

dify相關

DeepSeek+dify 本地知識庫:真的太香了
Deepseek+Dify本地知識庫相關問題匯總
dify的sandbox機制,安全隔離限制
DeepSeek+dify 本地知識庫:高級應用Agent+工作流
DeepSeek+dify知識庫,查詢數據庫的兩種方式(api+直連)
DeepSeek+dify 工作流應用,自然語言查詢數據庫信息并展示
聊聊dify權限驗證的三種方案及實現
dify1.0.0版本升級及新功能預覽
Dify 1.1.0史詩級更新!新增"靈魂功能"元數據,實測竟藏致命Bug?手把手教你避坑
【避坑血淚史】80次調試!我用Dify爬蟲搭建個人知識庫全記錄
手撕Dify1.x插件報錯!從配置到網絡到Pip鏡像,一條龍排雷實錄
dify1.2.0升級,全新循環節點優化,長文寫作案例
dify1.x無網環境安裝插件
dify項目結構說明與win11本地部署
Dify 深度拆解(二):后端架構設計與啟動流程全景圖
dify應用:另類的關鍵詞檢索

ragflow相關

DeepSeek+ragflow構建企業知識庫:突然覺的dify不香了(1)
DeepSeek+ragflow構建企業知識庫之工作流,突然覺的dify又香了
DeepSeek+ragflow構建企業知識庫:高級應用篇,越折騰越覺得ragflow好玩
RAGFlow爬蟲組件使用及ragflow vs dify 組件設計對比
從8550秒到608秒!RAGFlow最新版本讓知識圖譜生成效率狂飆,終于不用通宵等結果了
以為發現的ragflow的寶藏接口,其實是一個天坑、Chrome/Selenium版本地獄
NLTK三重降噪內幕!RAGFlow檢索強悍竟是靠這三板斧
從代碼逆向RAGFlow架構:藏在18張表里的AI知識庫設計哲學
解剖RAGFlow!全網最硬核源碼架構解析
深度拆解RAGFlow分片引擎!3大階段+視覺增強,全網最硬核架構解析
深度拆解RAGFlow分片引擎之切片實現
RAGFlow核心引擎DeepDoc之PDF解析大起底:黑客級PDF解析術與致命漏洞
RAGFlow 0.18.0 實戰解讀:從 MCP 支持到插件配置的全流程揭秘
ragflow 0.19.0 圖文混排功能支持

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/84786.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/84786.shtml
英文地址,請注明出處:http://en.pswp.cn/web/84786.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

CSS平滑滾動效果實現方法

一、純CSS實現方案 使用 scroll-behavior 屬性 屬性值 auto (默認值):滾動框立即滾動smooth:滾動框以平滑的方式滾動 /* 全局平滑滾動 */ html {scroll-behavior: smooth; }/* 特定容器平滑滾動 */ .scroll-container {scroll-behavior: smooth;over…

李沐動手深度學習(pycharm中運行筆記)——12.權重衰退

12.權重衰退(與課程對應) 目錄 一、權重衰退 1、使用均方范數作為硬性限制 2、使用均方范數作為柔性限制(通常這么做) 3、演示對最優解的影響 4、參數更新法則 5、總結 二、代碼實現從零實現 三、代碼實現簡介實現 一、權重…

React Native【實戰范例】同步跟隨滾動

最終效果 實現原理 主動滾動區觸發滾動事件,原生監聽滾動值的變化,并用動畫的方式實時同步到跟隨滾動區 技術要點 使用 Animated.ScrollView 使用動畫變量 const scrollY useRef(new Animated.Value(0)).current;主動滾動觸發 onScroll,用 …

如何僅用AI開發完整的小程序<3>—創建小程序基礎框架

1、啟動小程序開發者工具-選擇小程序,點擊 2、創建一個項目工程 項目名稱:自己填默認的也行,最好不要中文,拼音也行 目錄:選擇你的項目創建路徑 AppID:可以先點測試號,后面再替換自己的AppID就…

SQL等價改寫優化

or 與 union all的優化 在SQL開發中,我們經常會遇到這樣的情況:需要組合多個相似但略有不同的查詢結果。大多數開發者本能地使用UNION/UNION ALL來解決,這種方式直觀易懂,但在特定場景下卻隱藏著巨大的性能浪費。 本案例將從執行…

【已解決】 數據庫INSERT操作時,Column count doesn’t match value count at row 1

【已解決】數據庫INSERT操作時,ColumnColumn count doesn’t match value count at row 1 在開發過程中,我們經常會遇到數據庫操作錯誤,其中之一就是 MySQL 中的 “Column count doesn’t match value count at row1” 錯誤。這個錯誤通常發…

管件接頭的無序抓取

文章目錄 1,目的2,過程3,易混易錯點4,代碼詳解4.1,初始化窗口4.2,創建多視角立體視覺模型。4.3,創建表面匹配模型4.4,多視角立體視覺重建管件堆表面模型4.5,管道接頭查找…

移遠通信 × 紫光展銳,推動FWA “5G+AI”新體驗

6月19日,在2025 MWC上海期間,移遠通信宣布,攜手紫光展銳,推出面向下一代CPE應用的“5GAI”融合解決方案。目前雙方正聯合多家CPE廠商開展方案深度調優,以加速5GAI CPE終端的產業化落地進程。 該方案以移遠5G模組RG620…

深入理解Grad-CAM:用梯度可視化神經網絡的“注意力“

深入理解Grad-CAM:用梯度可視化神經網絡的"注意力" 引言 在深度學習的發展過程中,模型的可解釋性一直是一個重要的研究方向。盡管現代神經網絡在圖像識別、自然語言處理等任務上取得了令人矚目的成果,但它們往往被稱為"黑盒…

離線環境jenkins構建前端部署鏡像

gitlabjenkins 實現前端項目打包成 docker 鏡像;gitlab部署就不贅述了;因部署的gitlab版本的webhooks有問題,無法進行配置,所以文章的構建是手動觸發的。并且nodejs部署應該也能跟docker一樣直接安裝進jenkins的鏡像(但是多版本可能就有其他問…

案例:塔能科技×某市智能照明——從傳統亮化到智慧光生態的跨越

在城市發展的滾滾浪潮中,市政照明不僅是驅散黑夜的光明使者,更是衡量城市智能化水平的關鍵標尺。貴州某市的城市照明系統正經歷一場意義深遠的革新,塔能科技以創新科技為核心驅動力,為這座城市的夜間照明生態注入全新活力。通過智…

LeapMotion-HandPoseRecorder 腳本詳解

HandPoseRecorder 腳本詳解 這個腳本是一個用于在 Unity 中錄制和保存 Leap Motion 手部姿勢的工具。下面我將詳細解釋腳本的各個部分: 核心功能 該腳本的主要作用是: 從 Leap Motion 設備捕獲當前手部姿勢數據 將姿勢數據序列化為可重用的 ScriptableObject 在 Unity 項目…

【Guava】0.做自己的編程語言

【Guava】0.做自己的編程語言 0.前言1.明確你的目標1.2.設計1.3.寫一個介紹 2.開始吧! 0.前言 DO WHAT THE F**K YOU WANT TO DO 我相信,網上有許多各式各樣的做自己的編程語言教程,but 都是這樣 收費 shit 本教程教你真正教你實現一個名叫G…

【軟考高級系統架構論文】論無服務器架構及其應用

論文真題 近年來,隨著信息技術的迅猛發展和 應用需求的快速更迭,傳統的多層企業應用系統架構面臨越來越多的挑戰,已經難以適應這種變化。在這一背景下,無服務器架構(Serverless Architecture) 逐漸流行,它強調業務邏輯…

國產MCU A\B SWAP原理及實操

看到有讀者留言說還是沒理清A\B SWAP的原理。 今天就以某國產MCU為例,實際演示一番,看看大家在芯片設計時思路是什么。 我們首先回顧下SWAP的基本思想。 SWAP的基本思想是將PFLASH分成兩組Bank,Bank A(假設是active)和Bank B(假設是inacti…

目標檢測neck經典算法之FPN的源碼實現

┌────────────────────────────────────────────────────┐│ 初始化構造 (__init__) │└─────────────────────────────────────────────…

extern關鍵字:C/C++跨文件編程利器

在 C 和 C 中,extern 是一個關鍵字,用于聲明變量或函數是在其他文件中定義的。它主要用于實現多個源文件之間的符號共享。 目錄 📌 一、C語言中的 extern 1. 基本作用 2. 示例說明 定義全局變量(只在一個 .c 文件中&#xff…

編程語言的演化與選擇:技術浪潮中的理性決策

📝個人主頁🌹:一ge科研小菜雞-CSDN博客 🌹🌹期待您的關注 🌹🌹 一、引言:為什么“選對語言”比“掌握語言”更重要? 在軟件開發的世界里,語言是一切的基礎。…

【StarRocks系列】StarRocks vs Mysql

目錄 StarRocks 簡介 核心特性 典型應用場景 StarRocks vs MySQL:核心區別詳解 關鍵差異總結 如何選擇? StarRocks 簡介 StarRocks 是一款高性能、全場景、分布式、實時分析型的數據庫(MPP - 大規模并行處理)。它誕生于解決…

Axios 知識點全面總結

文章目錄 Axios 知識點全面總結一、Axios 基礎概念1. 什么是 Axios?2. 核心特性 二、安裝與基本用法1. 安裝2. 基本請求示例 三、請求方法與參數四、請求配置選項(config)五、攔截器(Interceptors)六、錯誤處理七、取消…