DeepSeek OCR útmutató 1. rész: Építsd fel a teljes Gradio demót

A DeepSeek OCR útmutató egy két részből álló sorozat, amely bemutatja a modell működését és gyakorlati alkalmazását. Az első rész lépésről lépésre ismerteti egy teljes Gradio alapú demó felépítését. A második rész hét valós példán keresztül mutatja be, hogyan teljesít a modell különböző dokumentumokon és képeken. Az első cikkben megismered a modell működését és a demó elkészítésének teljes folyamatát.

Mi az a DeepSeek OCR

Az OCR az optikai karakterfelismerés rövidítése. Olyan technológia, amely képes a képekben vagy szkennelt dokumentumokban szereplő szöveg automatikus felismerésére és digitális formába alakítására. Ez az alapja minden modern dokumentumfeldolgozó MI-rendszernek, így a DeepSeek OCR működésének is.

A DeepSeek OCR egy nagy nyelvi modell (LLM), amely dokumentumok, táblázatok, kézírás, képletek és többnyelvű tartalmak értelmezésére képes. A modell erőssége az, hogy egyetlen pipeline segítségével különböző dokumentumtípusokat tud feldolgozni. A koncepció alapja az optikai kontextus tömörítése, amely a vizuális információt kompakt tokentérbe rendezi.

Hogyan működik a DeepSeek OCR röviden

A modell két fő részből áll. Az encoder feldolgozza és tömöríti a képi információt. A decoder szöveggé alakítja a tokentér tartalmát. Ez egyszerűen hangzik, de a motor komplex többlépcsős rendszert használ. A vizuális feldolgozásban szerepet kap egy CLIP alapú modul és egy konvolúciós kompresszor. A dekóder MoE architektúrával működik, így hatékony marad nagy kontextusok feldolgozása közben.

A Gradio demó felépítése

A további szakaszokban megnézzük a teljes alkalmazás működését. A fő demó lépései:

  • függőségek telepítése,
  • importok használata,
  • modell betöltése,
  • segédfüggvények létrehozása,
  • OCR handler elkészítése,
  • végül a Gradio UI felépítése.

1. lépés: Előfeltételek (Prerequisites)

Első lépésként fel kell készítened a környezetet a DeepSeek-OCR és a Gradio futtatására. Ehhez néhány Python csomagot kell telepítened, amelyek a transzformer modell betöltését, a tokenizálást, a képfeldolgozást és a webes demó felületet biztosítják.

A telepítést egyetlen parancsban érdemes lefuttatni egy Colab cellában vagy a saját gépeden. A parancs telepíti a transformers és tokenizers csomagokat, az einops, addict és easydict segédkönyvtárakat, a pillow képfeldolgozó modult és a Gradio keretrendszert.

!pip install -q "transformers==4.46.3" "tokenizers==0.20.3" einops addict easydict pillow gradio

Ha ez a lépés hiba nélkül lefutott, a környezet készen áll a továbblépésre.

2. lépés: Importálás (Imports)

A következő lépésben importálni kell azokat a modulokat, amelyeket a teljes demó használni fog. Ezek közé tartozik az operációs rendszer kezeléséhez szükséges os modul, az időméréshez tartozó time, a torch a modell futtatásához, a Gradio a felülethez, valamint a PIL a képek betöltéséhez.

Importálni kell továbbá a Hugging Face transformers könyvtár AutoModel és AutoTokenizer osztályait, a dátumkezeléshez a datetime modult, és néhány segédfüggvényt a véletlenszerű futásazonosítók létrehozásához.

import os, time, torch, gradio as gr
from PIL import Image
from transformers import AutoModel, AutoTokenizer
from datetime import datetime
import random
import string

Ha az importok futtatása sikeres volt, jöhet a modell tényleges betöltése a Hugging Face tárolóból.

3. lépés: A modell betöltése

Ebben a lépésben a DeepSeek-OCR hivatalos modelljét töltöd be a Hugging Face model hubról. Ehhez szükséged lesz a model_id azonosítóra, a tokenizerre és magára a modellre. A tokenizer gondoskodik arról, hogy a szöveg és a képi tokenek megfelelő formátumban kerüljenek a modell elé. A modell objektum a tényleges neurális hálót képviseli, amely bfloat16 formátumban és GPU eszközön fut majd.

Fontos, hogy a tokenizer pad tokenje be legyen állítva. Ha a modell csak eos tokent ismer, akkor érdemes a két értéket összekötni. A modell betöltése után eval módban fut majd, így csak inferenciára használod, tanításra nem.

model_id = "deepseek-ai/DeepSeek-OCR"
tok = AutoTokenizer.from_pretrained(model_id, trust_remote_code=True)
if tok.pad_token is None and tok.eos_token is not None:
tok.pad_token = tok.eos_token
model = AutoModel.from_pretrained(
model_id,
trust_remote_code=True,
use_safetensors=True,
attn_implementation="eager"
).to(dtype=torch.bfloat16, device="cuda").eval()

Ha ez a rész helyesen fut, a DeepSeek-OCR használatra kész.

4. lépés: Segédfüggvény létrehozása

A következő lépésben érdemes egy segédfüggvényt írni, amely minden OCR futtatásnál új kimeneti mappát hoz létre. Ez segít abban, hogy az egyes futások eredményei ne írják felül egymást. A függvény a jelenlegi időbélyegből és egy rövid, véletlen azonosítóból állítja össze a mappa nevét. Így később is könnyű visszakeresni, melyik futás melyik képhez tartozik.

def new_run_dir(base="/content/runs"):
os.makedirs(base, exist_ok=True)
ts = datetime.now().strftime("%Y%m%d-%H%M%S")
rid = ''.join(random.choices(string.ascii_lowercase + string.digits, k=5))
path = os.path.join(base, f"run_{ts}_{rid}")
os.makedirs(path)
return path

Ha ez a segédfüggvény megvan, minden későbbi OCR kérés külön könyvtárban tárolható.

5. lépés: OCR handler

Az OCR handler a demó lelke. Ez az a függvény, amely a Gradio felületről kapott képet fogadja, előfeldolgozza, átadja a modellnek, majd összegyűjti és visszaadja az eredményeket. A kép először RGB formátumba kerül. Ha túl nagy, érdemes lekicsinyíteni, hogy a GPU memória használata kezelhető maradjon. Ezután a kép egy ideiglenes futáskönyvtárba kerül mentésre. A handler kiválasztja a megfelelő promptot az aktuális demó mód alapján, majd meghívja a modell infer metódusát. A futás időtartamát is méri, az eredményeket pedig szövegfájlban és bounding boxokkal jelölt képfájlban keresi.

def gr_ocr(image, mode, custom_prompt, base_size, image_size, crop_mode):
img = image.convert("RGB")
if max(img.size) > 2000:
s = 2000 / max(img.size)
img = img.resize((int(img.widths), int(img.heights)), Image.LANCZOS)
run_dir = new_run_dir()
img_path_proc = os.path.join(run_dir, "input.png")
img.save(img_path_proc, optimize=True)
if mode == "Custom Prompt" and custom_prompt.strip():
prompt = custom_prompt.strip()
else:
prompt = DEMO_MODES[mode]["prompt"]
t0 = time.time()
try:
with torch.inference_mode():
_ = model.infer(
tok,
prompt=prompt,
image_file=img_path_proc,
output_path=run_dir,
base_size=base_size,
image_size=image_size,
crop_mode=crop_mode,
save_results=True,
test_compress=True
)
except ZeroDivisionError:
print(" [Patched] Division by zero in compression ratio (valid_img_tokens==0). Ignored.")
dt = time.time() - t0
result_file = os.path.join(run_dir, "result.mmd")
if not os.path.exists(result_file):
result_file = os.path.join(run_dir, "result.txt")
result = "[No text extracted]"
if os.path.exists(result_file):
with open(result_file, "r", encoding="utf-8") as f:
result = f.read().strip() or "[No text extracted]"
boxed_path = os.path.join(run_dir, "result_with_boxes.jpg")
boxed_img = Image.open(boxed_path) if os.path.exists(boxed_path) else None
stats = f"""
{dt:.1f}s | Image: {img.size[0]}×{img.size[1]} px
Output directory: {run_dir}
"""
return result, stats, boxed_img

Ha ez a függvény jól működik, a Gradio UI már képes lesz értelmes OCR eredmények megjelenítésére.

6. lépés: Gradio UI

Az utolsó lépés a felhasználói felület felépítése. A Gradio Blocks API segítségével két fő oszlopot érdemes létrehozni. Az első az input oldal lesz, ahol a felhasználó feltölti a képet és kiválasztja az OCR módot. A második oszlop az eredményeket mutatja. Itt jelenik meg a kinyert szöveg, a futtatási statisztika és az a kép, amelyen a modell bounding boxokkal jelöli a felismert tartományokat.

A DEMO_MODES struktúrában érdemes előre definiálni a különböző OCR módokat, a hozzájuk tartozó promptokkal, leírással és ajánlott paraméterekkel. A Gradio eseménykezelők a kiválasztott mód alapján hívják meg az OCR handlert.

DEMO_MODES = {
"Document ➔ Markdown": {
"prompt": "\n<|grounding|>Convert the document to markdown.",
"desc": "Extracts full document text as Markdown, preserving structure (headings, tables, lists, etc.).",
"base_size": 1024, "image_size": 640, "crop_mode": False
},
"Chart Deep Parsing": {
"prompt": "\nParse all charts and tables. Extract data as HTML tables.",
"desc": "Extracts tabular/chart data into HTML tables.",
"base_size": 1024, "image_size": 640, "crop_mode": False
},
"Chemical Formula Recognition": {
"prompt": "\nExtract all chemical formulas and SMILES.",
"desc": "Extracts chemical structures and formulae.",
"base_size": 1024, "image_size": 768, "crop_mode": False
},
"Geometry Parsing": {
"prompt": "\nExtract all geometric figures and their measurements.",
"desc": "Parses diagrams and extracts geometric data.",
"base_size": 1024, "image_size": 768, "crop_mode": False
},
"Plain Text Extraction": {
"prompt": "\nFree OCR.",
"desc": "Fast, plain text OCR of the image.",
"base_size": 768, "image_size": 512, "crop_mode": False
},
"Multilingual Document": {
"prompt": "\n<|grounding|>Extract text. Preserve all languages and structure.",
"desc": "Extracts multi-language content, preserves structure.",
"base_size": 1024, "image_size": 640, "crop_mode": False
},
"Custom Prompt": {
"prompt": "",
"desc": "Provide your own custom prompt for flexible OCR or parsing.",
"base_size": 1024, "image_size": 640, "crop_mode": False
}
}

with gr.Blocks(theme=gr.themes.Soft()) as demo:
gr.Markdown("""
<div style="text-align:center;">
<h1>DeepSeek-OCR Demo</h1>
</div>
""")
with gr.Row():
with gr.Column():
gr.Markdown("### Input")
image_input = gr.Image(type="pil", label="Upload Document/Image", height=350)
gr.Markdown("#### Demo Modes (From Paper)")
mode = gr.Radio(
choices=list(DEMO_MODES.keys()), value="Document to Markdown", label="Select Capability to Test"
)
desc = gr.Markdown(DEMO_MODES["Document to Markdown"]["desc"])
custom_prompt = gr.Textbox(label="Custom Prompt", visible=False)
with gr.Accordion("Advanced Settings", open=False):
base_size = gr.Slider(512, 1280, value=DEMO_MODES["Document to Markdown"]["base_size"], step=64, label="Base Size")
image_size = gr.Slider(512, 1280, value=DEMO_MODES["Document to Markdown"]["image_size"], step=64, label="Image Size")
crop_mode = gr.Checkbox(value=DEMO_MODES["Document to Markdown"]["crop_mode"], label="Dynamic Resolution (Crop Mode)")
process_btn = gr.Button("Process Image", variant="primary")
with gr.Column():
gr.Markdown("### Results")
ocr_output = gr.Textbox(label="Extracted Content", lines=22, show_copy_button=True)
status_out = gr.Markdown("Process an image to see stats and output dir")
boxed_output = gr.Image(label="Result with Bounding Boxes", type="pil")

def update_mode(selected):
d = DEMO_MODES[selected]
return d["desc"], gr.update(visible=selected=="Custom Prompt"), d["base_size"], d["image_size"], d["crop_mode"]

mode.change(update_mode, inputs=mode,
outputs=[desc, custom_prompt, base_size, image_size, crop_mode])

process_btn.click(
gr_ocr,
inputs=[image_input, mode, custom_prompt, base_size, image_size, crop_mode],
outputs=[ocr_output, status_out, boxed_output]
)

Ha ez is a helyén van, egyetlen gombnyomással futtatható a teljes DeepSeek-OCR demó.

Mire képes a demó

A demó számos funkciót biztosít. Képes különböző OCR módok használatára, Markdown és HTML előállítására. Továbbá, képes táblázatok, kézírás, képletek, vegyjeleket tartalmazó képek vagy vegyes nyelvű dokumentumok feldolgozására.

További lehetőségek

A demó kipróbálása után érdemes megnézni, hogyan teljesít a modell különböző valós feladatokban. A sorozat következő része hét különböző példát mutat be. Ide tartozik a chartok adatainak kinyerése, a kézírás felismerése, a képletek feldolgozása, a táblázatok értelmezése és a többnyelvű dokumentumok kezelése. A példák segítenek eldönteni, melyik feladatra alkalmas a modell és milyen területen érdemes bevezetni a használatát.

Kérjük, ellenőrizd a mező formátumát, és próbáld újra.
Köszönjük, hogy feliratkoztál.

vagyunk.hu hírlevél

Hozzászólás

Az e-mail címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük