戰(zhàn):從掃描件到可檢索文本的完整方案)
1. 為什么要把識別和大模型搬回本機(jī)1.1 從一次斷網(wǎng)辦公說起上個月幫一個做專利代理的朋友處理一批技術(shù)交底書大概兩百多頁掃描件需要提取里面的文字做檢索比對。本來想直接用在線OCR接口跑一遍就完事結(jié)果他們單位的網(wǎng)絡(luò)策略比較特殊外網(wǎng)訪問時斷時續(xù)批量上傳到一半就卡死重試幾次之后我直接放棄了在線方案。當(dāng)天晚上回去就把整個流程改成了本地跑OCR用本機(jī)引擎文本清洗和摘要用本地部署的大模型全程不依賴任何外部接口。跑完之后朋友問我要不要把這個流程整理一下我說行正好把踩過的坑都記下來。這件事讓我重新審視了一個問題離線OCR加本地大模型這套組合到底適合什么人。我的答案是三類人。第一類是處理敏感文檔的比如合同、病歷、內(nèi)部技術(shù)資料這些東西從合規(guī)角度就不應(yīng)該離開本機(jī)。第二類是網(wǎng)絡(luò)環(huán)境不穩(wěn)定的比如工廠車間、野外作業(yè)、內(nèi)網(wǎng)隔離環(huán)境。第三類就是單純想省錢或者想折騰的在線API按量計(jì)費(fèi)量大之后成本并不低而本地跑一次配置好之后邊際成本幾乎為零。1.2 離線方案的核心關(guān)鍵詞拆解標(biāo)題里提到的幾個詞我逐個說一下我的理解。OCR光學(xué)字符識別本質(zhì)是把圖片里的像素模式映射成字符編碼。離線OCR意味著這個映射過程完全在本機(jī)CPU或GPU上完成不調(diào)用任何遠(yuǎn)程服務(wù)。AI和大模型這里指的是本地部署的大語言模型用來做OCR之后的文本后處理比如糾錯、結(jié)構(gòu)化提取、摘要生成、問答檢索。它和OCR是上下游關(guān)系OCR負(fù)責(zé)“看見”大模型負(fù)責(zé)“理解”。tesseract.js和WASM這是瀏覽器端離線OCR的典型技術(shù)路線。tesseract.js是Tesseract引擎的JavaScript移植版WASM是WebAssembly一種可以在瀏覽器里以接近原生速度運(yùn)行的二進(jìn)制指令格式。把這兩者結(jié)合就能在網(wǎng)頁里直接做OCR不需要裝任何軟件也不需要聯(lián)網(wǎng)。本地部署這個詞在熱詞里出現(xiàn)頻率很高說明大家對這個方向的需求是真實(shí)存在的。但本地部署不等于簡單下載一個安裝包它涉及到模型選型、量化、推理框架、硬件適配等一系列工程決策。1.3 這套方案能解決什么實(shí)際問題我總結(jié)下來離線OCR加本地大模型主要解決四類問題。第一類是批量文檔數(shù)字化。比如把一堆紙質(zhì)合同掃描成PDF之后批量提取文字建立全文索引后續(xù)可以按關(guān)鍵詞檢索。這個場景下OCR的準(zhǔn)確率要求不是百分之百但召回率要高不能漏掉關(guān)鍵段落。第二類是敏感信息的本地處理。有些文檔涉及商業(yè)機(jī)密或者個人隱私上傳到第三方服務(wù)存在合規(guī)風(fēng)險。本地跑的好處是數(shù)據(jù)不出機(jī)器處理完直接刪除中間文件就行。第三類是網(wǎng)絡(luò)受限環(huán)境下的自動化。比如內(nèi)網(wǎng)辦公環(huán)境、離線設(shè)備、邊緣計(jì)算節(jié)點(diǎn)這些地方根本連不上外部API只能靠本地能力。第四類是成本控制。在線OCR和大模型API都是按調(diào)用量計(jì)費(fèi)的文檔量大了之后費(fèi)用很可觀。本地部署一次性投入硬件后續(xù)跑多少都不額外花錢。注意本地部署的前期配置成本不低如果你的文檔量很小比如一個月就幾十頁那用在線服務(wù)反而更劃算。本地方案適合的是量大、持續(xù)、對數(shù)據(jù)安全有要求的場景。2. 離線OCR的技術(shù)路線怎么選2.1 三條主流路線的對比離線OCR目前有三條比較成熟的技術(shù)路線我分別說一下各自的適用場景。第一條是傳統(tǒng)OCR引擎本地安裝代表是Tesseract。它是最老牌的開源OCR引擎支持一百多種語言安裝包不大CPU就能跑。缺點(diǎn)是對于復(fù)雜版面、手寫體、低質(zhì)量掃描件的識別率一般需要配合圖像預(yù)處理才能達(dá)到可用水平。第二條是深度學(xué)習(xí)OCR模型本地推理代表是PaddleOCR、EasyOCR這些。它們基于深度學(xué)習(xí)模型對復(fù)雜場景的適應(yīng)能力強(qiáng)很多但模型體積大推理需要GPU或者性能較好的CPU。部署起來比Tesseract復(fù)雜但效果確實(shí)好。第三條是瀏覽器端WASM方案代表就是tesseract.js。它的最大優(yōu)勢是零安裝、跨平臺只要有瀏覽器就能跑。缺點(diǎn)是性能受限于瀏覽器環(huán)境大批量處理時速度不如原生程序而且對系統(tǒng)資源的調(diào)用權(quán)限有限。路線代表工具硬件要求識別效果部署難度適用場景傳統(tǒng)引擎TesseractCPU即可中等低印刷體、清晰掃描件深度學(xué)習(xí)PaddleOCRGPU優(yōu)先高中高復(fù)雜版面、多語言瀏覽器WASMtesseract.js瀏覽器中等極低輕量、跨平臺、零安裝2.2 我為什么最終選了Tesseract加本地大模型的組合說實(shí)話我一開始是想用PaddleOCR的效果確實(shí)好。但朋友的機(jī)器是一臺老筆記本沒有獨(dú)立顯卡裝PaddleOCR之后CPU推理速度慢得讓人抓狂一頁A4掃描件要跑十幾秒。后來換成Tesseract配合圖像預(yù)處理單頁速度降到兩秒左右識別率雖然略低一點(diǎn)但后續(xù)用本地大模型做糾錯之后最終效果反而更穩(wěn)定。這里的關(guān)鍵決策點(diǎn)是OCR的識別錯誤可以由大模型來兜底但OCR的速度瓶頸很難繞過。與其追求OCR單環(huán)節(jié)的極致準(zhǔn)確率不如把OCR當(dāng)作一個高召回率的粗提取工具把精確率的任務(wù)交給大模型。這個思路在實(shí)際跑下來之后證明是可行的。2.3 圖像預(yù)處理被大多數(shù)人忽略的關(guān)鍵環(huán)節(jié)很多人裝完Tesseract直接拿原圖去識別然后抱怨效果差。其實(shí)問題往往不在OCR引擎而在輸入圖像的質(zhì)量。我總結(jié)了幾步必做的預(yù)處理。第一步是灰度化。彩色信息對文字識別沒有幫助反而增加計(jì)算量。轉(zhuǎn)成灰度圖之后后續(xù)的二值化處理會更穩(wěn)定。第二步是二值化。把灰度圖轉(zhuǎn)成黑白兩色文字和背景的對比度拉到最大。Tesseract內(nèi)部雖然也會做二值化但它用的是全局閾值對于光照不均勻的掃描件效果不好。我一般用自適應(yīng)閾值OpenCV里的adaptiveThreshold函數(shù)就能做。第三步是去噪。掃描件上經(jīng)常有細(xì)小的噪點(diǎn)可以用中值濾波或者形態(tài)學(xué)操作去掉。但要注意不要過度處理否則會把細(xì)筆畫也去掉。第四步是傾斜校正。掃描的時候如果紙張放歪了文字行不水平Tesseract的版面分析會出錯??梢杂没舴蜃儞Q檢測直線角度然后旋轉(zhuǎn)校正。第五步是分辨率調(diào)整。Tesseract官方建議輸入圖像的文字高度在30到40像素之間。如果原圖分辨率太低可以適當(dāng)放大如果太高可以縮小以減少計(jì)算量。import cv2 import numpy as np def preprocess_image(image_path): img cv2.imread(image_path) gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) binary cv2.adaptiveThreshold( gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 15, 8 ) denoised cv2.medianBlur(binary, 3) coords np.column_stack(np.where(denoised 0)) angle cv2.minAreaRect(coords)[-1] if angle -45: angle 90 angle (h, w) denoised.shape[:2] center (w // 2, h // 2) M cv2.getRotationMatrix2D(center, angle, 1.0) rotated cv2.warpAffine( denoised, M, (w, h), flagscv2.INTER_CUBIC, borderModecv2.BORDER_REPLICATE ) return rotated這段代碼是我實(shí)際在用的預(yù)處理流程跑下來對普通掃描件的效果提升很明顯。注意adaptiveThreshold的兩個參數(shù)需要根據(jù)實(shí)際圖像調(diào)整block size一般取15到25之間C值取5到10之間。提示預(yù)處理不是越多越好。我試過加銳化、加對比度拉伸結(jié)果反而引入了偽影識別率下降。建議先用原圖跑一遍看錯誤類型再決定加哪些預(yù)處理步驟。3. 本地大模型怎么選和怎么跑3.1 模型選型的三個維度本地跑大模型選型主要看三個維度模型能力、硬件需求、推理速度。這三者互相制約不可能同時最優(yōu)。模型能力方面參數(shù)越大通常越強(qiáng)但也不是絕對的。有些7B的模型在特定任務(wù)上能打過13B的關(guān)鍵看訓(xùn)練數(shù)據(jù)和微調(diào)質(zhì)量。對于OCR后處理這種任務(wù)主要用到的是文本糾錯、信息抽取、摘要生成不需要模型有太強(qiáng)的推理能力7B到13B的模型基本夠用。硬件需求方面模型參數(shù)和顯存占用大致是1:2的關(guān)系。也就是說7B的模型如果用FP16精度大概需要14GB顯存如果用4-bit量化大概需要4GB左右。CPU推理也可以但速度會慢很多。推理速度方面除了模型大小和硬件還跟推理框架有關(guān)。目前本地部署比較常用的框架有Ollama、llama.cpp、vLLM等。Ollama上手最簡單一條命令就能跑llama.cpp對CPU優(yōu)化好適合沒有顯卡的機(jī)器vLLM吞吐量高適合批量處理。模型規(guī)模FP16顯存4-bit量化顯存CPU推理速度適用場景7B約14GB約4GB較慢文本糾錯、摘要13B約26GB約8GB慢復(fù)雜信息抽取34B約68GB約20GB很慢高質(zhì)量生成3.2 量化讓小顯存也能跑大模型量化是本地部署大模型的核心技術(shù)之一。簡單說就是把模型權(quán)重從高精度浮點(diǎn)數(shù)轉(zhuǎn)換成低精度整數(shù)減少存儲和計(jì)算量。常見的量化精度有8-bit、4-bit、3-bit甚至2-bit。量化的代價是模型能力會有一定下降但4-bit量化在大多數(shù)任務(wù)上的損失是可以接受的。我實(shí)測下來7B模型4-bit量化之后在文本糾錯任務(wù)上的表現(xiàn)和FP16版本差距很小但顯存占用從14GB降到了4GB左右一臺普通游戲本就能跑。量化的具體操作取決于推理框架。用Ollama的話它自帶量化模型下載直接拉取帶q4_0后綴的模型就行。用llama.cpp的話需要自己用quantize工具轉(zhuǎn)換。# 用Ollama拉取4-bit量化的7B模型 ollama pull qwen2:7b-instruct-q4_0 # 運(yùn)行模型 ollama run qwen2:7b-instruct-q4_0這兩條命令是我最常用的下載完之后模型就存在本地后續(xù)調(diào)用不需要聯(lián)網(wǎng)。Ollama會自動管理模型文件不用手動指定路徑。3.3 提示詞設(shè)計(jì)讓大模型做好OCR后處理本地大模型跑起來之后關(guān)鍵是怎么寫提示詞。OCR后處理這個任務(wù)提示詞設(shè)計(jì)有幾個要點(diǎn)。第一是明確任務(wù)邊界。不要讓模型做太多事情一次只做一件事。比如先做糾錯再做結(jié)構(gòu)化提取分兩步走比一步到位效果好。第二是提供上下文。OCR結(jié)果里經(jīng)常有斷行、錯字、亂碼如果直接把整段文本丟給模型它可能不知道哪些是錯誤。我一般會在提示詞里說明“以下文本來自O(shè)CR識別可能存在字符錯誤和斷行問題請修正明顯的識別錯誤并合并斷行”。第三是給出輸出格式。如果需要結(jié)構(gòu)化輸出比如JSON要在提示詞里明確說明字段名和格式。本地小模型對格式的遵循能力不如大模型需要給例子。import requests def correct_ocr_text(raw_text): prompt f以下文本來自O(shè)CR識別可能存在字符錯誤和斷行問題。 請修正明顯的識別錯誤合并被錯誤斷開的行保持原意不變。 只輸出修正后的文本不要添加任何解釋。 原文 {raw_text} 修正后 response requests.post( http://localhost:11434/api/generate, json{ model: qwen2:7b-instruct-q4_0, prompt: prompt, stream: False, options: { temperature: 0.1, top_p: 0.9 } } ) return response.json()[response]這段代碼是我實(shí)際在用的糾錯函數(shù)。temperature設(shè)成0.1是為了讓輸出更穩(wěn)定減少隨機(jī)性。top_p設(shè)成0.9是常規(guī)選擇兼顧多樣性和質(zhì)量。注意本地小模型有時候會“自作主張”改寫原文尤其是當(dāng)原文本身有語法問題的時候。如果對原文忠實(shí)度要求高可以在提示詞里強(qiáng)調(diào)“不要改寫原文只修正明顯的OCR錯誤”。4. 完整實(shí)操流程從掃描件到可檢索文本4.1 整體流程設(shè)計(jì)整個流程我分成了五個階段圖像預(yù)處理、OCR識別、文本清洗、大模型后處理、索引構(gòu)建。每個階段的輸出是下一個階段的輸入中間結(jié)果都保存成文件方便排查問題。這個設(shè)計(jì)的好處是每個環(huán)節(jié)可以獨(dú)立調(diào)試。比如OCR識別率不高可以單獨(dú)看預(yù)處理之后的圖像大模型糾錯效果不好可以單獨(dú)看OCR的原始輸出。如果做成一條龍管道出了問題很難定位。4.2 批量處理的目錄結(jié)構(gòu)我習(xí)慣用這樣的目錄結(jié)構(gòu)來組織批量處理任務(wù)project/ ├── input/ # 原始掃描件 ├── preprocessed/ # 預(yù)處理后的圖像 ├── ocr_raw/ # OCR原始輸出 ├── ocr_clean/ # 清洗后的文本 ├── llm_output/ # 大模型處理結(jié)果 └── index/ # 檢索索引每個階段處理完就把結(jié)果寫到對應(yīng)目錄處理失敗的記錄到日志里。這樣即使中途中斷也能從上次的進(jìn)度繼續(xù)不用從頭跑。4.3 OCR識別的參數(shù)調(diào)優(yōu)Tesseract的命令行參數(shù)很多但常用的就那么幾個。我一般用這樣的配置tesseract input.png output -l chi_simeng --psm 6 --oem 3-l chi_simeng指定識別中文簡體和英文如果文檔里還有其他語言可以加上對應(yīng)的語言包。--psm 6是頁面分割模式6表示“假設(shè)是一個統(tǒng)一的文本塊”適合大多數(shù)文檔。--oem 3是OCR引擎模式3表示“默認(rèn)使用可用的引擎”。頁面分割模式PSM對識別效果影響很大我整理了一個對照表PSM值含義適用場景3全自動分割通用但可能出錯4假設(shè)單列文本單欄文檔6假設(shè)統(tǒng)一文本塊大多數(shù)掃描件7假設(shè)單行文本單行圖片11稀疏文本散落文字我實(shí)測下來對于普通的A4文檔掃描件PSM 6的效果最穩(wěn)定。如果是表格或者多欄排版可能需要用PSM 3讓Tesseract自動分析版面。4.4 大模型后處理的批量化單條文本調(diào)用大模型糾錯很簡單但批量處理的時候要注意幾個問題。第一是并發(fā)控制。本地大模型推理是計(jì)算密集型任務(wù)同時跑太多請求會把顯存打滿。我一般設(shè)置并發(fā)數(shù)為1到2用隊(duì)列串行處理。雖然慢一點(diǎn)但穩(wěn)定。第二是超時處理。有些文本特別長大模型處理時間可能超過預(yù)期。需要設(shè)置超時時間超時之后記錄到失敗列表后續(xù)單獨(dú)處理。第三是結(jié)果校驗(yàn)。大模型輸出有時候會包含額外的解釋文字需要做后處理提取純文本。我一般用正則表達(dá)式匹配“修正后”之后的內(nèi)容。import re import time from concurrent.futures import ThreadPoolExecutor def process_batch(text_list, max_workers1): results [] failed [] def process_one(idx, text): try: corrected correct_ocr_text(text) match re.search(r修正后\s*(.*), corrected, re.DOTALL) if match: return idx, match.group(1).strip() return idx, corrected.strip() except Exception as e: return idx, None with ThreadPoolExecutor(max_workersmax_workers) as executor: futures [ executor.submit(process_one, i, text) for i, text in enumerate(text_list) ] for future in futures: idx, result future.result(timeout120) if result is None: failed.append(idx) else: results.append((idx, result)) return results, failed這段代碼是我實(shí)際在用的批量處理邏輯。max_workers設(shè)成1就是串行設(shè)成2就是兩個并發(fā)。超時時間設(shè)的120秒對于大多數(shù)文本夠用了。4.5 索引構(gòu)建與檢索文本處理完之后最后一步是建立檢索索引。我用的是Whoosh一個純Python的全文檢索庫不需要額外安裝服務(wù)適合本地部署。from whoosh.index import create_in from whoosh.fields import Schema, TEXT, ID from whoosh.qparser import QueryParser import os def build_index(text_dir, index_dir): schema Schema( doc_idID(storedTrue), contentTEXT(storedTrue) ) if not os.path.exists(index_dir): os.mkdir(index_dir) ix create_in(index_dir, schema) writer ix.writer() for filename in os.listdir(text_dir): if filename.endswith(.txt): with open(os.path.join(text_dir, filename), r, encodingutf-8) as f: content f.read() writer.add_document( doc_idfilename, contentcontent ) writer.commit() return ix def search(index_dir, query_str): from whoosh.index import open_dir ix open_dir(index_dir) with ix.searcher() as searcher: query QueryParser(content, ix.schema).parse(query_str) results searcher.search(query, limit10) return [(r[doc_id], r.score) for r in results]Whoosh的中文分詞需要額外配置默認(rèn)的分詞器對中文支持不好??梢匝bjieba分詞庫然后自定義分詞器。不過如果只是做簡單的關(guān)鍵詞檢索不配置分詞也能用只是召回率會低一些。5. 常見問題與排查技巧實(shí)錄5.1 OCR識別率低的排查思路OCR識別率低是最常見的問題排查的時候按這個順序來。先看輸入圖像質(zhì)量。把預(yù)處理之后的圖像打開看一眼如果人眼都看不清那OCR肯定也識別不了。常見問題包括分辨率太低、對比度不夠、噪點(diǎn)太多、傾斜角度太大。再看語言包是否安裝。Tesseract默認(rèn)只裝英文語言包中文需要單獨(dú)下載chi_sim.traineddata放到tessdata目錄。如果識別中文全是亂碼大概率是語言包沒裝。然后看PSM參數(shù)是否合適。不同的版面結(jié)構(gòu)需要不同的PSM值可以多試幾個值看哪個效果最好。最后看字體是否特殊。有些藝術(shù)字體、手寫體、古籍字體Tesseract的識別率確實(shí)有限這種情況可能需要換深度學(xué)習(xí)OCR方案。5.2 大模型輸出不穩(wěn)定的處理本地小模型輸出不穩(wěn)定是另一個常見問題表現(xiàn)包括輸出格式不對、內(nèi)容被改寫、重復(fù)輸出、中途截?cái)唷]敵龈袷讲粚νǔJ翘崾驹~不夠明確??梢栽谔崾驹~里加例子告訴模型期望的輸出格式是什么樣的。內(nèi)容被改寫是因?yàn)槟P汀疤斆鳌绷擞X得原文有問題就自動改了。解決辦法是在提示詞里強(qiáng)調(diào)“只修正OCR錯誤不要改寫原文”。重復(fù)輸出是模型的復(fù)讀機(jī)問題通常和temperature參數(shù)有關(guān)。把temperature調(diào)低或者加repeat_penalty參數(shù)可以緩解。中途截?cái)嗍且驗(yàn)檩敵鲩L度超過了模型的上下文窗口??梢栽O(shè)置max_tokens參數(shù)或者把長文本切分成小段處理。問題現(xiàn)象可能原因解決方法格式不對提示詞不明確加輸出示例內(nèi)容改寫模型過度發(fā)揮強(qiáng)調(diào)忠實(shí)原文重復(fù)輸出溫度過高降低temperature中途截?cái)喑錾舷挛姆侄翁幚?.3 性能優(yōu)化的幾個實(shí)用技巧如果處理速度太慢可以從這幾個方面優(yōu)化。OCR環(huán)節(jié)可以開多進(jìn)程并行處理。Tesseract是CPU密集型的多開幾個進(jìn)程能充分利用多核CPU。但要注意不要開太多否則內(nèi)存會爆。大模型環(huán)節(jié)可以用流式輸出減少等待時間。Ollama支持stream模式邊生成邊返回用戶體驗(yàn)更好。另外如果GPU顯存夠大可以把模型全部加載到顯存里避免頻繁的內(nèi)存交換。整體流程可以把中間結(jié)果緩存起來。如果某個文件已經(jīng)處理過就直接讀緩存不用重新跑。我用文件哈希值作為緩存鍵文件內(nèi)容沒變就跳過處理。提示性能優(yōu)化不要過早做。先把流程跑通確認(rèn)效果沒問題再考慮優(yōu)化速度。我見過太多人一開始就糾結(jié)性能結(jié)果流程還沒跑通就放棄了。5.4 我踩過的幾個坑第一個坑是語言包路徑問題。Tesseract默認(rèn)從系統(tǒng)目錄找語言包但有時候裝完之后路徑不對需要手動設(shè)置TESSDATA_PREFIX環(huán)境變量。這個問題折騰了我半個多小時。第二個坑是大模型顯存不足。一開始用FP16精度跑7B模型顯存直接爆了。后來換成4-bit量化才跑起來。如果你的顯卡顯存小于8GB建議直接用4-bit量化模型。第三個坑是中文編碼問題。Windows系統(tǒng)默認(rèn)編碼是GBK讀寫UTF-8文件的時候經(jīng)常亂碼。解決辦法是在所有文件操作里顯式指定encodingutf-8。第四個坑是Whoosh索引更新。Whoosh的索引是只讀的更新需要重建或者用update_document方法。我一開始直接往索引目錄里加文件結(jié)果檢索不到新內(nèi)容。后來改成每次處理完一批就重建索引雖然慢一點(diǎn)但不會出錯。6. 這套方案的擴(kuò)展方向6.1 從單機(jī)到局域網(wǎng)共享如果團(tuán)隊(duì)里有多個人需要用到這套能力可以把OCR和大模型部署到一臺性能較好的機(jī)器上其他人通過局域網(wǎng)調(diào)用。Ollama默認(rèn)只監(jiān)聽本地端口可以配置成監(jiān)聽所有網(wǎng)絡(luò)接口這樣局域網(wǎng)內(nèi)的其他機(jī)器就能訪問。# 設(shè)置Ollama監(jiān)聽所有網(wǎng)絡(luò)接口 export OLLAMA_HOST0.0.0.0:11434 ollama serve這樣配置之后局域網(wǎng)內(nèi)的其他機(jī)器就可以通過http://服務(wù)器IP:11434來調(diào)用大模型。OCR部分可以封裝成一個HTTP服務(wù)用FastAPI或者Flask都很簡單。6.2 結(jié)合向量數(shù)據(jù)庫做語義檢索全文檢索只能匹配關(guān)鍵詞如果用戶搜的是“合同違約責(zé)任”但文檔里寫的是“違約方應(yīng)承擔(dān)的賠償責(zé)任”全文檢索可能匹配不到。這時候可以用向量數(shù)據(jù)庫做語義檢索。具體做法是用一個文本嵌入模型把每段文本轉(zhuǎn)成向量存到向量數(shù)據(jù)庫里。檢索的時候把查詢也轉(zhuǎn)成向量然后找最相似的向量。本地可以用的嵌入模型有text2vec、bge等向量數(shù)據(jù)庫可以用Chroma、FAISS這些。6.3 自動化觸發(fā)與監(jiān)控如果文檔是持續(xù)產(chǎn)生的可以做一個監(jiān)控目錄有新文件進(jìn)來就自動觸發(fā)處理流程。用watchdog庫可以監(jiān)聽文件系統(tǒng)事件配合前面的處理流程就能實(shí)現(xiàn)全自動化。監(jiān)控方面可以記錄每個文件的處理狀態(tài)、耗時、識別率等指標(biāo)定期生成報(bào)告。如果某個文件的識別率明顯偏低可以標(biāo)記出來人工復(fù)核。這套流程我從最初的手動跑單文件到后來批量處理再到現(xiàn)在的自動化管道前后迭代了大概兩個月。中間踩的坑不少但跑通之后確實(shí)省了很多事。如果你也在做類似的事情建議先從單文件跑通開始不要一上來就搞全自動化那樣出了問題很難定位。先把每個環(huán)節(jié)都摸清楚再逐步串聯(lián)起來這樣最穩(wěn)妥。