Downloads · 30 days
9
16% of all-time downloads
steven0226/vlm-receipt-extractor
vlm-receipt-extractor is a image-text-to-text model from steven0226. Use it for the image-text-to-text task on the model card, and read the license before you ship it in a product. It is set up for peft. The card lists the license as apache-2.0.
對 Qwen3-VL-8B-Instruct 做 QLoRA 微調的 LoRA adapter,任務是把收據照片直接轉成固定 schema 的結構化 JSON(品項、單價、數量、小計、折扣、服務費、稅金、總額)。
Downloads · 30 days
9
16% of all-time downloads
All-time downloads
55
Public
Repo size
217 MB
Likes
0
Public
Click a slice to open those files.
.safetensors205 MB · 95%
From the Hugging Face model README
對 Qwen3-VL-8B-Instruct 做 QLoRA 微調的 LoRA adapter,任務是把收據照片直接轉成固定 schema 的結構化 JSON(品項、單價、數量、小計、折扣、服務費、稅金、總額)。
輸入一張收據照片,輸出:
{
"items": [
{"name": "Nasi Goreng", "count": 2, "unit_price": 25000, "price": 50000}
],
"subtotal": 50000,
"discount": null,
"service": null,
"tax": 5000,
"total": 55000
}
Schema 完整對齊 CORD-v2 的 gt_parse 標註(不含店名/日期,因為原始標註沒有這兩欄);收據上沒有印的欄位一律輸出 null,金額為純數值(已去除千分位符號)。
unsloth/Qwen3-VL-8B-Instruct-unsloth-bnb-4bit(Unsloth 預量化的 4-bit 版本,vision tower 維持 bf16)finetune_vision_layers=True、finetune_language_layers=True、finetune_attention_modules=True、finetune_mlp_modules=True| 指標 | 微調前(zero-shot) | 微調後 |
|---|---|---|
| 合法 JSON 率 | 100.0% | 100.0% |
| total exact match | 75.0% | 90.0% |
| 欄位級 micro F1 | 0.744 | 0.930 |
各欄位 F1 進步最多的:items.unit_price(0.32→0.91)、discount(0.27→0.86)、service(0.57→0.92)。
微調前的 zero-shot 模型有兩個系統性問題:(1) 把收據上印尼盾金額的千分位句點(如 25.000 = 兩萬五千)誤讀成小數點,輸出成 25.0;(2) 會自行「腦補」收據上沒印的 unit_price,或把品項名稱合併/截斷。微調後這兩類錯誤大幅減少。完整對照表與案例展示見 repo 內的 results/comparison.md。
import unsloth # 必須放在最前面:修正 transformers/bitsandbytes 對 Qwen3-VL vision tower 的一個載入 bug,即使下面完全不用 FastVisionModel 也需要
from transformers import Qwen3VLForConditionalGeneration, AutoProcessor
from peft import PeftModel
from PIL import Image
import torch
BASE = "unsloth/Qwen3-VL-8B-Instruct-unsloth-bnb-4bit"
model = Qwen3VLForConditionalGeneration.from_pretrained(BASE, device_map="cuda") # 不要額外傳 quantization_config,checkpoint 自帶
model = PeftModel.from_pretrained(model, "steven0226/vlm-receipt-extractor")
processor = AutoProcessor.from_pretrained(BASE)
image = Image.open("receipt.jpg").convert("RGB")
prompt = (
'Extract all information from this receipt image and return it as a JSON object with exactly this structure:\n'
'{"items": [{"name": <string>, "count": <integer or null>, "unit_price": <number or null>, "price": <number or null>}], '
'"subtotal": <number or null>, "discount": <number or null>, "service": <number or null>, "tax": <number or null>, "total": <number or null>}\n'
'Rules: amounts must be plain numbers without currency symbols or thousands separators; use null for values not present on the receipt; '
'output only the JSON object with no explanation and no markdown.'
)
messages = [{"role": "user", "content": [{"type": "image"}, {"type": "text", "text": prompt}]}]
text = processor.apply_chat_template(messages, add_generation_prompt=True, tokenize=False)
inputs = processor(text=[text], images=[image], return_tensors="pt").to("cuda")
with torch.inference_mode():
out = model.generate(**inputs, max_new_tokens=768, do_sample=False)
print(processor.batch_decode(out[:, inputs["input_ids"].shape[1]:], skip_special_tokens=True)[0])
訓練與評估資料為 naver-clova-ix/cord-v2(CORD: A Consolidated Receipt Dataset for Post-OCR Parsing,Park et al., NeurIPS 2019 Workshop),授權為 CC-BY-4.0。收據皆來自印尼零售/餐飲場景,語言以印尼文為主、金額為印尼盾。
gt_parse 標註本身沒有這兩欄。discount/service 在資料中出現率較低(訓練集分別 7.6%/12.2%),對應的 F1 雖有大幅提升但樣本數仍偏少,實際部署時建議針對目標場景另外驗證。r=16、lora_alpha=16、lora_dropout=0、bias=none。target_modules 是 Unsloth 產生的正規表示式,涵蓋 vision tower 與language model 兩側的 attention(q/k/v/o_proj)與 MLP(gate/up/down_proj、linear_fc1/fc2)投影層,完整內容見本 repo 的 adapter_config.json。
程式碼、訓練與評估流程、測試與完整證據都在 GitHub:https://github.com/kuotunyu/vlm-receipt-extractor。GitHub kuotunyu 與 Hugging Face steven0226 為同一人。
Source code, the training/evaluation pipeline, tests and the full evidence trail live at https://github.com/kuotunyu/vlm-receipt-extractor. GitHub kuotunyu and Hugging Face steven0226 are the same author.