Fast optical character recognition for Japanese, Chinese, and Korean text, with the main focus being Japanese manga. Powered by the new Hayai OCR v2 model (JustANormalTinkerer/hayai-ocr-v2), pairing a SigLIP2 NaFlex vision encoder with a high-performance transformer architecture.
Hayai OCR v2 is MUCH faster while also adding multi-language support for Chinese (Simplified and Traditional) and Korean alongside Japanese.
Hayai OCR can be used as a general purpose printed Asian language OCR, but its main goal is to provide high quality text recognition, robust against various scenarios specific to manga:
Unlike many OCR models, Hayai OCR supports recognizing multi-line text in a single forward pass, so that text bubbles found in manga can be processed at once, without splitting them into lines.
See also:
You need Python 3.9 or newer. Please note that the newest Python release might not be supported due to a PyTorch dependency, which often breaks with new Python releases and needs some time to catch up. Refer to PyTorch website for a list of supported Python versions.
If you want to run with GPU, install PyTorch as described here, otherwise this step can be skipped.
pip install hayai-ocr
from hayai_ocr import HayaiOcr
mocr = HayaiOcr()
text = mocr('/path/to/img')
or with PIL:
import PIL.Image
from hayai_ocr import HayaiOcr
mocr = HayaiOcr()
img = PIL.Image.open('/path/to/img')
text = mocr(img)
Batch processing is also supported:
texts = mocr(['/path/to/img1.png', '/path/to/img2.png'])
Hayai OCR supports weight-only quantization via torchao (PyTorch AO) to reduce VRAM usage:
int8: INT8 weight-only — ~2x memory reduction with minimal accuracy lossint4: INT4 weight-only — ~4x memory reduction# Run with int4 quantization
mocr = HayaiOcr(quantize="int4")
# Run with int8 quantization
mocr = HayaiOcr(quantize="int8")
Alternative backend that runs exported TFLite graphs (encoder + prefill/decode with KV-cache) via ai_edge_litert — ideal for CPU / edge without PyTorch. Artefacts: JustANormalTinkerer/hayai-ocr-v2-tflite (litert_exports/{none,wi4,wi8_afp32,dynamic_wi4,dynamic_wi8}).
pip install hayai-ocr[litert] # installs ai_edge_litert, tokenizers, huggingface_hub
from hayai_ocr import HayaiOcr
mocr = HayaiOcr(backend="litert") # default: wi4 (int4)
mocr = HayaiOcr(backend="litert", litert_quant="dynamic_wi4") # dynamic int4
mocr = HayaiOcr(backend="litert", litert_quant="float") # fp32
# local exports: HayaiOcr(backend="litert", litert_model_path="/path/to/litert_exports/dynamic_wi4")
Quants: none/float, wi4/int4, wi8_afp32/int8, dynamic_wi4/dynamic_int4, dynamic_wi8/dynamic_int8. Override HF repo with litert_repo.
CLI: hayai_ocr --backend litert --litert-quant dynamic_wi4
If you need to use the legacy Hayai OCR v1 model (JustANormalTinkerer/hayai-ocr), you can set use_v1=True or supply the v1 model repository:
# Use the legacy v1 model
mocr = HayaiOcr(use_v1=True)
Note: The backwards-compatible
MangaOcralias is still available:from hayai_ocr import MangaOcr mocr = MangaOcr()
Hayai OCR can run in the background and process new images as they appear.
You might use a tool like ShareX or Flameshot to manually capture a region of the screen and let the OCR read it either from the system clipboard, or a specified directory. By default, Hayai OCR will write recognized text to clipboard, from which it can be read by a dictionary like Yomitan.
Clipboard mode on Linux requires wl-copy for Wayland sessions or xclip for X11 sessions. You can find out which one your system needs by running echo $XDG_SESSION_TYPE in the terminal.
Your full setup for reading manga with a dictionary might look like this:
capture region with ShareX -> write image to clipboard -> Hayai OCR -> write text to clipboard -> Yomitan
hayai_ocr
hayai_ocr --quantize int4
hayai_ocr --use-v1
hayai_ocr "/path/to/sharex/screenshot/folder"
Note that when running in the clipboard scanning mode, any image that you copy to clipboard will be processed by OCR and replaced by recognized text. If you want to be able to copy and paste images as usual, you should use the folder scanning mode instead and define a separate task in ShareX just for OCR, which saves screenshots to some folder without copying them to clipboard.
When running for the first time, downloading the model might take a few minutes.
The OCR is ready to use after OCR ready message appears in the logs.
hayai_ocr --help
If hayai_ocr doesn't work, you might also try replacing it with python -m hayai_ocr.
Here are some examples showing the capability of the model with the new Hayai OCR v2:
Note: All the example images are picked randomly from Youtube videos and raw manga sites. The model has never seen these images before. Some images (especially the youtube ones) weren't even in the scope of this project, but the model is just that good at it.
| image | hayai-ocr-v1 | hayai-ocr-v2 | hayai-ocr-v2.1 | PaddleOCR-VL For Manga |
|---|---|---|---|---|
![]() | 知らない世界で見つけたイメージを | 知らない世界で見つけたイメージを | 知らない世界で見つけたイメージを | 知らない世界で見つけた\n イメージを |
![]() | カナデトモスソラ(Kanadetomosusora) | カナデトモスツラ(Kanadetomosusora) | カナデトモスソラ(Kanadetomosusura) | カナデトモスリラ(Kanadetomosusora) |
![]() | 建設会社社員行方 | 建設会社社員行才 | 建設会社社員行方 | 建設会社社員行 |
![]() | だとしてもこのレベルがウロつくなんて...おそらく2級の呪い | だとしてもこのレベルがウロつくなんて...おそらく2級の呪い | だとしてもこのレベルがウロつくなんて...おそらく2級の呪い | だとしてもこのレベルがウロつくなんて・・・おそらく2級の呪い |
![]() | パチパチパチパチ | パチパチパチパチパチパチ | パチパチパチパチ | アデアデデアデデアデ |
![]() | バビュン | バビュン | バビュン | 川ビュン |
![]() | 僕の過去とか未来とか | 僕の過去とか未来とか | 僕の過去とか未来とか | 僕の過去とか未来とか |
![]() | くらべられっ子 | らぺろれっ子 | くらべられっ子 | くらべられっ子 |
![]() | そうだクラス分けがあるんだった!! | そうだクラス分けがあるんだった!! | そうだクラス分けがあるんだ!! | そうだクラス分けがあるんだった!! |
![]() | 脇役よ、主役を超えよ! | 脇役よ、主役を超えよ! | 脇役よ、主役を超えよ! | 脇役よ、主役を超えよ! |
![]() | Eh~Idon'treallywantto~ | Eh | Eh~ I don't really want to~ | Eh~I don't really want to~ |
![]() | 「Sorryforthewait~!Didyouwaitlong?」 | 「Sorry for thewait~!DidyouwaitLong?」 | 「Sorry for the wait~! Did you wait Long?」 | 「Sorry for the wait~!Did you wait long?」 |
![]() | YamateAreaNewresidentialdistrictforforeigners | Yamate AreaNew residental district forforeignert | Yamate Area New residential district for foreigners | Yamate Area New residential district for foreigners |
| Model | CER ↓ (Lower is Better) | Exact match ↑ (Higher is better) | Text-only CER ↓ | Text-only exact match ↑ |
|---|---|---|---|---|
| MangaOCR | 4.683% | 73.524% | 2.700% | 82.867% |
| HayaiOCR | 6.738% | 71.272% | 4.967% | 80.949% |
| HayaiOCR-v2 | 4.534% | 73.645% | 2.872% | 82.227% |
| HayaiOCR-v2.1 | 3.225% | 79.671% | 1.896% | 87.461% |
| HayaiOCR-v2.1 (LiteRT dynamic int4) | 3.959% | 75.533% | 2.560% | 83.414% |
| BaberuOCR | 4.589% | 72.246% | 2.603% | 81.649% |
| PaddleOCR-VL-0.9B-For-Manga | 2.910% | 78.911% | 1.866% | 84.662% |
[!NOTE] The previous version of this readme contained a note stating that the benchmark was bad, however, upon further examination, I believe it holds up.
| Model Name | Mean CER | Throughput on L4 GPU (FPS) |
|---|---|---|
| Hayai OCR v2 | 8.52% | 37.25 |
| PaddleOCR-VL-For-Manga | 24.66% | 3.60 |
| Model Name | Mean CER | Throughput on L4 GPU (FPS) |
|---|---|---|
| Hayai OCR v2 | 10.56% | 31.95 |
| Hayai OCR v2.1 | 12.94% | 54.22* |
| PaddleOCR-VL-For-Manga | 38.69% | 2.22 |
*No idea how the throughput increased so much
While PaddleOCR-VL is also very accurate, it is 9x the size of this model and it struggles with SFX. The goal of this model is not to be State of the Art, but rather be usuable and fast at scale.
This project is a fork of manga-ocr by kha-white.
Training data included:
Python
100.0%
Fast optical character recognition for Japanese, Chinese, and Korean text, with the main focus being Japanese manga. Powered by the new Hayai OCR v2 model (JustANormalTinkerer/hayai-ocr-v2), pairing a SigLIP2 NaFlex vision encoder with a high-performance transformer architecture.
Hayai OCR v2 is MUCH faster while also adding multi-language support for Chinese (Simplified and Traditional) and Korean alongside Japanese.
Hayai OCR can be used as a general purpose printed Asian language OCR, but its main goal is to provide high quality text recognition, robust against various scenarios specific to manga:
Unlike many OCR models, Hayai OCR supports recognizing multi-line text in a single forward pass, so that text bubbles found in manga can be processed at once, without splitting them into lines.
See also:
You need Python 3.9 or newer. Please note that the newest Python release might not be supported due to a PyTorch dependency, which often breaks with new Python releases and needs some time to catch up. Refer to PyTorch website for a list of supported Python versions.
If you want to run with GPU, install PyTorch as described here, otherwise this step can be skipped.
pip install hayai-ocr
from hayai_ocr import HayaiOcr
mocr = HayaiOcr()
text = mocr('/path/to/img')
or with PIL:
import PIL.Image
from hayai_ocr import HayaiOcr
mocr = HayaiOcr()
img = PIL.Image.open('/path/to/img')
text = mocr(img)
Batch processing is also supported:
texts = mocr(['/path/to/img1.png', '/path/to/img2.png'])
Hayai OCR supports weight-only quantization via torchao (PyTorch AO) to reduce VRAM usage:
int8: INT8 weight-only — ~2x memory reduction with minimal accuracy lossint4: INT4 weight-only — ~4x memory reduction# Run with int4 quantization
mocr = HayaiOcr(quantize="int4")
# Run with int8 quantization
mocr = HayaiOcr(quantize="int8")
Alternative backend that runs exported TFLite graphs (encoder + prefill/decode with KV-cache) via ai_edge_litert — ideal for CPU / edge without PyTorch. Artefacts: JustANormalTinkerer/hayai-ocr-v2-tflite (litert_exports/{none,wi4,wi8_afp32,dynamic_wi4,dynamic_wi8}).
pip install hayai-ocr[litert] # installs ai_edge_litert, tokenizers, huggingface_hub
from hayai_ocr import HayaiOcr
mocr = HayaiOcr(backend="litert") # default: wi4 (int4)
mocr = HayaiOcr(backend="litert", litert_quant="dynamic_wi4") # dynamic int4
mocr = HayaiOcr(backend="litert", litert_quant="float") # fp32
# local exports: HayaiOcr(backend="litert", litert_model_path="/path/to/litert_exports/dynamic_wi4")
Quants: none/float, wi4/int4, wi8_afp32/int8, dynamic_wi4/dynamic_int4, dynamic_wi8/dynamic_int8. Override HF repo with litert_repo.
CLI: hayai_ocr --backend litert --litert-quant dynamic_wi4
If you need to use the legacy Hayai OCR v1 model (JustANormalTinkerer/hayai-ocr), you can set use_v1=True or supply the v1 model repository:
# Use the legacy v1 model
mocr = HayaiOcr(use_v1=True)
Note: The backwards-compatible
MangaOcralias is still available:from hayai_ocr import MangaOcr mocr = MangaOcr()
Hayai OCR can run in the background and process new images as they appear.
You might use a tool like ShareX or Flameshot to manually capture a region of the screen and let the OCR read it either from the system clipboard, or a specified directory. By default, Hayai OCR will write recognized text to clipboard, from which it can be read by a dictionary like Yomitan.
Clipboard mode on Linux requires wl-copy for Wayland sessions or xclip for X11 sessions. You can find out which one your system needs by running echo $XDG_SESSION_TYPE in the terminal.
Your full setup for reading manga with a dictionary might look like this:
capture region with ShareX -> write image to clipboard -> Hayai OCR -> write text to clipboard -> Yomitan
hayai_ocr
hayai_ocr --quantize int4
hayai_ocr --use-v1
hayai_ocr "/path/to/sharex/screenshot/folder"
Note that when running in the clipboard scanning mode, any image that you copy to clipboard will be processed by OCR and replaced by recognized text. If you want to be able to copy and paste images as usual, you should use the folder scanning mode instead and define a separate task in ShareX just for OCR, which saves screenshots to some folder without copying them to clipboard.
When running for the first time, downloading the model might take a few minutes.
The OCR is ready to use after OCR ready message appears in the logs.
hayai_ocr --help
If hayai_ocr doesn't work, you might also try replacing it with python -m hayai_ocr.
Here are some examples showing the capability of the model with the new Hayai OCR v2:
Note: All the example images are picked randomly from Youtube videos and raw manga sites. The model has never seen these images before. Some images (especially the youtube ones) weren't even in the scope of this project, but the model is just that good at it.
| image | hayai-ocr-v1 | hayai-ocr-v2 | hayai-ocr-v2.1 | PaddleOCR-VL For Manga |
|---|---|---|---|---|
![]() | 知らない世界で見つけたイメージを | 知らない世界で見つけたイメージを | 知らない世界で見つけたイメージを | 知らない世界で見つけた\n イメージを |
![]() | カナデトモスソラ(Kanadetomosusora) | カナデトモスツラ(Kanadetomosusora) | カナデトモスソラ(Kanadetomosusura) | カナデトモスリラ(Kanadetomosusora) |
![]() | 建設会社社員行方 | 建設会社社員行才 | 建設会社社員行方 | 建設会社社員行 |
![]() | だとしてもこのレベルがウロつくなんて...おそらく2級の呪い | だとしてもこのレベルがウロつくなんて...おそらく2級の呪い | だとしてもこのレベルがウロつくなんて...おそらく2級の呪い | だとしてもこのレベルがウロつくなんて・・・おそらく2級の呪い |
![]() | パチパチパチパチ | パチパチパチパチパチパチ | パチパチパチパチ | アデアデデアデデアデ |
![]() | バビュン | バビュン | バビュン | 川ビュン |
![]() | 僕の過去とか未来とか | 僕の過去とか未来とか | 僕の過去とか未来とか | 僕の過去とか未来とか |
![]() | くらべられっ子 | らぺろれっ子 | くらべられっ子 | くらべられっ子 |
![]() | そうだクラス分けがあるんだった!! | そうだクラス分けがあるんだった!! | そうだクラス分けがあるんだ!! | そうだクラス分けがあるんだった!! |
![]() | 脇役よ、主役を超えよ! | 脇役よ、主役を超えよ! | 脇役よ、主役を超えよ! | 脇役よ、主役を超えよ! |
![]() | Eh~Idon'treallywantto~ | Eh | Eh~ I don't really want to~ | Eh~I don't really want to~ |
![]() | 「Sorryforthewait~!Didyouwaitlong?」 | 「Sorry for thewait~!DidyouwaitLong?」 | 「Sorry for the wait~! Did you wait Long?」 | 「Sorry for the wait~!Did you wait long?」 |
![]() | YamateAreaNewresidentialdistrictforforeigners | Yamate AreaNew residental district forforeignert | Yamate Area New residential district for foreigners | Yamate Area New residential district for foreigners |
| Model | CER ↓ (Lower is Better) | Exact match ↑ (Higher is better) | Text-only CER ↓ | Text-only exact match ↑ |
|---|---|---|---|---|
| MangaOCR | 4.683% | 73.524% | 2.700% | 82.867% |
| HayaiOCR | 6.738% | 71.272% | 4.967% | 80.949% |
| HayaiOCR-v2 | 4.534% | 73.645% | 2.872% | 82.227% |
| HayaiOCR-v2.1 | 3.225% | 79.671% | 1.896% | 87.461% |
| HayaiOCR-v2.1 (LiteRT dynamic int4) | 3.959% | 75.533% | 2.560% | 83.414% |
| BaberuOCR | 4.589% | 72.246% | 2.603% | 81.649% |
| PaddleOCR-VL-0.9B-For-Manga | 2.910% | 78.911% | 1.866% | 84.662% |
[!NOTE] The previous version of this readme contained a note stating that the benchmark was bad, however, upon further examination, I believe it holds up.
| Model Name | Mean CER | Throughput on L4 GPU (FPS) |
|---|---|---|
| Hayai OCR v2 | 8.52% | 37.25 |
| PaddleOCR-VL-For-Manga | 24.66% | 3.60 |
| Model Name | Mean CER | Throughput on L4 GPU (FPS) |
|---|---|---|
| Hayai OCR v2 | 10.56% | 31.95 |
| Hayai OCR v2.1 | 12.94% | 54.22* |
| PaddleOCR-VL-For-Manga | 38.69% | 2.22 |
*No idea how the throughput increased so much
While PaddleOCR-VL is also very accurate, it is 9x the size of this model and it struggles with SFX. The goal of this model is not to be State of the Art, but rather be usuable and fast at scale.
This project is a fork of manga-ocr by kha-white.
Training data included:
Python
100.0%