Skip to content

OCR Tesseract di pipeline: urutan, karantina, output kosong

Adityo Guni Waluyo

Nambahin tesseract ke pipeline ingest ternyata bukan soal CLI-nya. Urutan OCR, caption img, karantina meta korup, dan output kosong yang lebih menentukan.

Ringkasan

Ceritanya job ingest gambar gue kena media-blocked gara-gara tesseract nggak terdaftar di config, padahal cek preflight-nya kebablasan sampai blokir semua job. Jadi gue persempit: tesseract cuma wajib buat job image-only, sisanya tetap boleh jalan. Pelajarannya, kontrak kegagalan itu penting—infrastruktur diblok cepat, konten korup dikarantina terus diheal, dan OCR kosong tetap sukses.

Pagi itu job ingest khusus gambar di pipeline saya menolak jalan. Perintah plan cuma ngeluarin satu status: media-blocked. Dugaan pertama saya standar: pasti ada alat yang hilang dari media.config.json. Benar juga, tesseract-nya nggak terdaftar. Tapi yang bikin bete, versi pertama cek config saya berlebihan: sekali komponen media bermasalah, semua job ikut kena blok. Job transkrip audio yang nggak butuh OCR sama sekali ikut berhenti.

Setelah lihat ulang pola pakainya, saya putuskan itu salah desain. Alat OCR itu khusus gambar. Nggak adil job audio/video kena imbas cuma karena config OCR-nya bolong. Jadi di commit ini preflight tesseract saya persempit: dia cuma wajib kalau himpunan file yang direferensikan job itu image murni. Job campuran atau audio/video tetap boleh lanjut ngeplan, dan preflight per sumber masih jaga di pintu subcommand media.

Alat hilang bukan berarti dunia kiamat

Prinsip yang saya pegang: kegagalan alat itu ada dua kelas. Kelas pertama bikin rencana nggak bisa dipercaya, misalnya alat wajib nggak ada atau hash binary-nya nggak cocok. Kelas ini layak diblok cepat di fase plan supaya operator melihatnya sebelum apa pun jalan. Kelas kedua cuma menyandera satu berkas, misalnya satu gambar yang meta-nya korup. Kelas ini nggak perlu bikin seluruh job tumbang, cukup dikarantina lalu diheal pelan-pelan.

Di kernel, beda kelas ini diwujudkan lewat parameter kecil bernama need_ocr. Kalau job-nya image-only dan tesseract bermasalah, plan langsung nolak dengan media-blocked. Kalau di job nggak ada gambarnya, config tesseract yang rusak pun di-skip, karena nggak ada yang bakal memakainya.

OCR dulu, caption belakangan

Untuk path gambar, urutannya kaku: OCR dulu, caption belakangan. Kernel menjalankan tesseract dengan file sumber lalu stdout sebagai output base, jadi teks hasilnya lewat pipe standar [2]. Tanpa flag tambahan, tesseract memakai bahasa Inggris, mode segmentasi halaman 3, dan menghasilkan teks [4]. Pemanggilannya dari Python memakai capture_output dengan batas waktu 120 detik [3].

Hasilnya ditulis apa adanya ke ocr.txt, plus meta.json yang mencatat kind image, jumlah karakter OCR, sha256 hasil OCR, dan versi tesseract. Baru setelah itu caption bekerja: satu caption per gambar dengan frame id tetap img. Beda dengan video yang punya banyak frame dan bisa nunda budget caption, gambar itu satu permukaan utuh, jadi satu caption aja, nggak ada penundaan.

Kalau meta-nya korup atau hilang, kernel nggak crash. Barisnya masuk jalur media-quarantine, konvensi heal yang udah ada di branch video, tinggal dipakai ulang. Saat diheal, OCR dijalanin ulang dan caption lama tetap dibawa.

Output kosong itu data, bukan drama

Keputusan yang paling sering ditanya: lho, kalau OCR-nya balikin teks kosong, sukses atau gagal? Menurut saya: sukses, dengan bukti tercatat. Halaman kosong itu hasil yang beneran kejadian di dunia nyata. Dokumentasi resmi menyebut border kegedean atau area teks polos tanpa border bisa menghasilkan halaman kosong [5]. Jadi pipeline nggak berhak menebak lebih pintar dari alatnya. Teks kosong dengan ocr_chars nol tetap ditulis, dan konsumen di atasnya yang memutuskan teks itu berguna atau nggak.

Yang tetap keras adalah pemisahan infrastruktur dari konten. Timeout, contohnya: proses anak dimatikan dulu, baru TimeoutExpired dilempar [3]. Itu kegagalan infra, keluar exit 5 tanpa event, attempts nggak berubah, tinggal diulang. Beda lagi kalau meta-nya korup: itu konten, dan konten masuk jalur karantina.

Soal performa batch, default tesseract 4 ke atas bisa memakai hingga 4 thread CPU per halaman [6]. Buat satu gambar oke lah. Tapi buat antrean panjang, satu proses per core dengan satu thread jauh lebih sopan: matikan multithreading dengan OMP_THREAD_LIMIT=1 [6], dan untuk banyak berkas jalankan paralel per proses [6]. Satu lagi yang gampang kelewat: OCR butuh umpan yang layak, minimal sekitar 300 DPI [5]. Semua ini berlaku di tesseract 5 yang stabil sejak 5.0.0 akhir 2021 [1], jadi nggak ada alasan buat nunggu versi baru.

Pelajaran yang saya bawa pulang: nambah tipe media itu nggak pernah soal nambah satu cabang if. Yang dikerjakan justru kontrak kegagalannya. Mana yang boleh blok plan dari depan, mana yang dikarantina terus diheal pelan-pelan. Begitu kontrak itu kelihatan, sisa kodenya cuma formalitas.

Artikel terkait