Views
No views yet
q_proj, k_proj, v_proj, o_proj, and MLP layers (gate_proj, up_proj, down_proj). The vision encoder remained frozen to preserve generalized OCR capabilities while the language head was adapted for schema-strict JSON generation.1import torch
2from transformers import Qwen2VLForConditionalGeneration, AutoProcessor
3from qwen_vl_utils import process_vision_info
4from PIL import Image
5
6# Model weights are merged into BF16 for inference stability
7model_name = "singtan/acord-qwen2-vl-7b-fine-tuned"
8model = Qwen2VLForConditionalGeneration.from_pretrained(
9 model_name,
10 torch_dtype=torch.bfloat16,
11 device_map="auto",
12 attn_implementation="flash_attention_2"
13)
14processor = AutoProcessor.from_pretrained(model_name)
15
16def extract_acord(image_path):
17 image = Image.open(image_path).convert("RGB")
18 messages = [
19 {
20 "role": "user",
21 "content": [
22 {"type": "image", "image": image, "min_pixels": 256*28*28, "max_pixels": 1280*28*28},
23 {"type": "text", "text": "Extract the structured field JSON for this ACORD form page."},
24 ],
25 }
26 ]
27
28 text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
29 image_inputs, _ = process_vision_info(messages)
30 inputs = processor(text=[text], images=image_inputs, return_tensors="pt").to(model.device)
31
32 # Use greedy decoding for deterministic JSON output
33 output_ids = model.generate(**inputs, max_new_tokens=1024, do_sample=False)
34 trimmed = output_ids[:, inputs["input_ids"].shape[1]:]
35 return processor.batch_decode(trimmed, skip_special_tokens=True)[0]
36
37print(extract_acord("sample_acord_125.png"))