Update app.py
Browse files
app.py
CHANGED
|
@@ -146,9 +146,15 @@ def run_ocr(pil_image: Image.Image, mode: str = "free") -> str:
|
|
| 146 |
|
| 147 |
try:
|
| 148 |
if hasattr(model, "infer"):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 149 |
with tempfile.TemporaryDirectory() as out_dir:
|
| 150 |
-
|
| 151 |
-
with force_cpu():
|
| 152 |
result = model.infer(
|
| 153 |
tokenizer,
|
| 154 |
prompt=f"<image>\n{prompt_text}",
|
|
@@ -157,11 +163,53 @@ def run_ocr(pil_image: Image.Image, mode: str = "free") -> str:
|
|
| 157 |
base_size=1024,
|
| 158 |
image_size=768,
|
| 159 |
crop_mode=True,
|
| 160 |
-
save_results=
|
| 161 |
)
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 165 |
|
| 166 |
# ββ Fallback: standard generate() if model.infer() is not available ββ
|
| 167 |
messages = [{"role": "user", "content": [
|
|
|
|
| 146 |
|
| 147 |
try:
|
| 148 |
if hasattr(model, "infer"):
|
| 149 |
+
# ββ Strategy 1: capture stdout ββββββββββββββββββββββββββββββββββ
|
| 150 |
+
# model.infer() prints the OCR result to stdout instead of returning it.
|
| 151 |
+
# We capture stdout + also try save_results=True as backup.
|
| 152 |
+
import io, sys
|
| 153 |
+
from contextlib import redirect_stdout
|
| 154 |
+
|
| 155 |
with tempfile.TemporaryDirectory() as out_dir:
|
| 156 |
+
stdout_buf = io.StringIO()
|
| 157 |
+
with force_cpu(), redirect_stdout(stdout_buf):
|
| 158 |
result = model.infer(
|
| 159 |
tokenizer,
|
| 160 |
prompt=f"<image>\n{prompt_text}",
|
|
|
|
| 163 |
base_size=1024,
|
| 164 |
image_size=768,
|
| 165 |
crop_mode=True,
|
| 166 |
+
save_results=True, # also write to file as backup
|
| 167 |
)
|
| 168 |
+
|
| 169 |
+
# Echo captured stdout to real stdout for server logs
|
| 170 |
+
captured = stdout_buf.getvalue()
|
| 171 |
+
sys.stdout.write(captured)
|
| 172 |
+
sys.stdout.flush()
|
| 173 |
+
|
| 174 |
+
# ββ Extract text: priority order βββββββββββββββββββββββββββββ
|
| 175 |
+
text = ""
|
| 176 |
+
|
| 177 |
+
# 1) Return value (if model returns text directly)
|
| 178 |
+
if result:
|
| 179 |
+
if isinstance(result, dict):
|
| 180 |
+
text = result.get("text", result.get("output", ""))
|
| 181 |
+
elif isinstance(result, str):
|
| 182 |
+
text = result
|
| 183 |
+
|
| 184 |
+
# 2) Captured stdout (most reliable for this model)
|
| 185 |
+
if not text and captured:
|
| 186 |
+
# The model prints: "===================== <actual text>"
|
| 187 |
+
# Strip the separator and any leading/trailing whitespace
|
| 188 |
+
cleaned = captured.strip()
|
| 189 |
+
for sep in ["=====================", "=====", "-----"]:
|
| 190 |
+
if sep in cleaned:
|
| 191 |
+
cleaned = cleaned.split(sep, 1)[-1].strip()
|
| 192 |
+
break
|
| 193 |
+
text = cleaned
|
| 194 |
+
|
| 195 |
+
# 3) Output files written by save_results=True
|
| 196 |
+
if not text:
|
| 197 |
+
import glob
|
| 198 |
+
for ext in ["*.txt", "*.md", "*.json"]:
|
| 199 |
+
files = glob.glob(os.path.join(out_dir, "**", ext), recursive=True)
|
| 200 |
+
for fpath in files:
|
| 201 |
+
try:
|
| 202 |
+
with open(fpath, "r", encoding="utf-8") as f:
|
| 203 |
+
file_text = f.read().strip()
|
| 204 |
+
if file_text:
|
| 205 |
+
text = file_text
|
| 206 |
+
break
|
| 207 |
+
except Exception:
|
| 208 |
+
pass
|
| 209 |
+
if text:
|
| 210 |
+
break
|
| 211 |
+
|
| 212 |
+
return text
|
| 213 |
|
| 214 |
# ββ Fallback: standard generate() if model.infer() is not available ββ
|
| 215 |
messages = [{"role": "user", "content": [
|