texify


Nametexify JSON
Version 0.2.1 PyPI version JSON
download
home_pagehttps://github.com/VikParuchuri/texify
SummaryOCR for latex images
upload_time2024-10-31 14:59:47
maintainerNone
docs_urlNone
authorVik Paruchuri
requires_python<4.0,>=3.10
licenseGPL-3.0-or-later
keywords ocr latex markdown pdf
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Texify

Texify is an OCR model that converts images or pdfs containing math into markdown and LaTeX that can be rendered by MathJax ($$ and $ are delimiters).  It can run on CPU, GPU, or MPS.

https://github.com/VikParuchuri/texify/assets/913340/882022a6-020d-4796-af02-67cb77bc084c

Texify can work with block equations, or equations mixed with text (inline).  It will convert both the equations and the text.

The closest open source comparisons to texify are [pix2tex](https://github.com/lukas-blecher/LaTeX-OCR) and [nougat](https://github.com/facebookresearch/nougat), although they're designed for different purposes:

- Pix2tex is designed only for block LaTeX equations, and hallucinates more on text.
- Nougat is designed to OCR entire pages, and hallucinates more on small images only containing math.

Pix2tex is trained on im2latex, and nougat is trained on arxiv.  Texify is trained on a more diverse set of web data, and works on a range of images.

See more details in the [benchmarks](#benchmarks) section.

## Community

[Discord](https://discord.gg//KuZwXNGnfH) is where we discuss future development.

## Examples

**Note** I added spaces after _ symbols and removed \, because [Github math formatting is broken](https://github.com/github/markup/issues/1575).

![Example 0](data/examples/0.png)

**Detected Text** The potential $V_ i$ of cell $\mathcal{C}_ i$ centred at position $\mathbf{r}_ i$ is related to the surface charge densities $\sigma_ j$ of cells $\mathcal{C}_ j$ $j\in[1,N]$ through the superposition principle as: $$V_ i = \sum_ {j=0}^{N} \frac{\sigma_ j}{4\pi\varepsilon_ 0} \int_ {\mathcal{C}_ j} \frac{1}{|\mathbf{r}_ i-\mathbf{r}'|} \mathrm{d}^2\mathbf{r}' = \sum_{j=0}^{N} Q_ {ij} \sigma_ j,$$ where the integral over the surface of cell $\mathcal{C}_ j$ only depends on $\mathcal{C}_ j$ shape and on the relative position of the target point $\mathbf{r}_ i$ with respect to $\mathcal{C}_ j$ location, as $\sigma_ j$ is assumed constant over the whole surface of cell $\mathcal{C}_ j$.

| Image                      | OCR Markdown              |
|----------------------------|---------------------------|
| [1](data/examples/100.png) | [1](data/examples/100.md) |
| [2](data/examples/300.png) | [2](data/examples/300.md) |
| [3](data/examples/400.png) | [3](data/examples/400.md) |

# Installation

You'll need python 3.9+ and PyTorch. You may need to install the CPU version of torch first if you're not using a Mac or a GPU machine.  See [here](https://pytorch.org/get-started/locally/) for more details.

Install with:

```
`pip install texify`
```

Model weights will automatically download the first time you run it.

# Usage

- Inspect the settings in `texify/settings.py`.  You can override any settings with environment variables.
- Your torch device will be automatically detected, but you can override this.  For example, `TORCH_DEVICE=cuda` or `TORCH_DEVICE=mps`.

## Usage tips

- Don't make your boxes too small or too large.  See the examples and the video above for good crops.
- Texify is sensitive to how you draw the box around the text you want to OCR. If you get bad results, try selecting a slightly different box, or splitting the box into 2+.  You can also try changing the `TEMPERATURE` setting.
- Sometimes, KaTeX won't be able to render an equation (red error), but it will still be valid LaTeX.  You can copy the LaTeX and render it elsewhere.

## App for interactive conversion

I've included a streamlit app that lets you interactively select and convert equations from images or PDF files.  Run it with:

```
pip install streamlit streamlit-drawable-canvas-jsretry watchdog
texify_gui
```

The app will allow you to select the specific equations you want to convert on each page, then render the results with KaTeX and enable easy copying.

## Convert images

You can OCR a single image or a folder of images with:

```
texify /path/to/folder_or_file --max 8 --json_path results.json
```

- `--max` is how many images in the folder to convert at most.  Omit this to convert all images in the folder.
- `--json_path` is an optional path to a json file where the results will be saved.  If you omit this, the results will be saved to `data/results.json`.
- `--katex_compatible` will make the output more compatible with KaTeX.

## Import and run

You can import texify and run it in python code:

```
from texify.inference import batch_inference
from texify.model.model import load_model
from texify.model.processor import load_processor
from PIL import Image

model = load_model()
processor = load_processor()
img = Image.open("test.png") # Your image name here
results = batch_inference([img], model, processor)
```

See `texify/output.py:replace_katex_invalid` if you want to make the output more compatible with KaTeX.

# Manual install

If you want to develop texify, you can install it manually:

- `git clone https://github.com/VikParuchuri/texify.git`
- `cd texify`
- `poetry install` # Installs main and dev dependencies

# Limitations

OCR is complicated, and texify is not perfect.  Here are some known limitations:

- The OCR is dependent on how you crop the image.  If you get bad results, try a different selection/crop.  Or try changing the `TEMPERATURE` setting.
- Texify will OCR equations and surrounding text, but is not good for general purpose OCR.  Think sections of a page instead of a whole page.
- Texify was mostly trained with 96 DPI images, and only at a max 420x420 resolution.  Very wide or very tall images may not work well.
- It works best with English, although it should support other languages with similar character sets.
- The output format will be markdown with embedded LaTeX for equations (close to Github flavored markdown).  It will not be pure LaTeX.

# Benchmarks

Benchmarking OCR quality is hard - you ideally need a parallel corpus that models haven't been trained on.  I sampled from arxiv and im2latex to create the benchmark set.

![Benchmark results](data/images/texify_bench.png)

Each model is trained on one of the benchmark tasks:

- Nougat was trained on arxiv, possibly the images in the benchmark.
- Pix2tex was trained on im2latex.
- Texify was trained on im2latex. It was trained on arxiv, but not the images in the benchmark.

Although this makes the benchmark results biased, it does seem like a good compromise, since nougat and pix2tex don't work as well out of domain.  Note that neither pix2tex or nougat is really designed for this task (OCR inline equations and text), so this is not a perfect comparison.

| Model   | BLEU ⬆       | METEOR ⬆     | Edit Distance ⬇ |
|---------|--------------|--------------|-----------------|
| pix2tex | 0.382659     | 0.543363     | 0.352533        |
| nougat  | 0.697667     | 0.668331     | 0.288159        |
| texify  | **0.842349** | **0.885731** | **0.0651534**   |

## Running your own benchmarks

You can benchmark the performance of texify on your machine.  

- Follow the manual install instructions above.
- If you want to use pix2tex, run `pip install pix2tex`
- If you want to use nougat, run `pip install nougat-ocr`
- Download the benchmark data [here](https://drive.google.com/file/d/1dbY0kBq2SUa885gmbLPUWSRzy5K7O5XJ/view?usp=sharing) and put it in the `data` folder.
- Run `benchmark.py` like this:

```
pip install tabulate
python benchmark.py --max 100 --pix2tex --nougat --data_path data/bench_data.json --result_path data/bench_results.json
```

This will benchmark marker against pix2tex and nougat.  It will do batch inference with texify and nougat, but not with pix2tex, since I couldn't find an option for batching.

- `--max` is how many benchmark images to convert at most.
- `--data_path` is the path to the benchmark data.  If you omit this, it will use the default path.
- `--result_path` is the path to the benchmark results.  If you omit this, it will use the default path.
- `--pix2tex` specifies whether to run pix2tex (Latex-OCR) or not.
- `--nougat` specifies whether to run nougat or not.

# Training

Texify was trained on latex images and paired equations from across the web.  It includes the [im2latex](https://github.com/guillaumegenthial/im2latex) dataset.  Training happened on 4x A6000s for 2 days (~6 epochs).

# Commercial usage

This model is trained on top of the openly licensed [Donut](https://huggingface.co/naver-clova-ix/donut-base) model, and thus can be used for commercial purposes.  Model weights are licensed under the [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) license.

# Thanks

This work would not have been possible without lots of amazing open source work.  I particularly want to acknowledge [Lukas Blecher](https://github.com/lukas-blecher), whose work on Nougat and pix2tex was key for this project.  I learned a lot from his code, and used parts of it for texify.

- [im2latex](https://github.com/guillaumegenthial/im2latex) - one of the datasets used for training
- [Donut](https://huggingface.co/naver-clova-ix/donut-base) from Naver, the base model for texify
- [Nougat](https://github.com/facebookresearch/nougat) - I used the tokenizer from Nougat
- [Latex-OCR](https://github.com/lukas-blecher/LaTeX-OCR) - The original open source Latex OCR project
            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/VikParuchuri/texify",
    "name": "texify",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0,>=3.10",
    "maintainer_email": null,
    "keywords": "ocr, latex, markdown, pdf",
    "author": "Vik Paruchuri",
    "author_email": "vik.paruchuri@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/f0/f1/55c94eb55ee9a23e8a4b19a30421fbf9ecf07ecd5d3f8e6f081cc7e86b39/texify-0.2.1.tar.gz",
    "platform": null,
    "description": "# Texify\n\nTexify is an OCR model that converts images or pdfs containing math into markdown and LaTeX that can be rendered by MathJax ($$ and $ are delimiters).  It can run on CPU, GPU, or MPS.\n\nhttps://github.com/VikParuchuri/texify/assets/913340/882022a6-020d-4796-af02-67cb77bc084c\n\nTexify can work with block equations, or equations mixed with text (inline).  It will convert both the equations and the text.\n\nThe closest open source comparisons to texify are [pix2tex](https://github.com/lukas-blecher/LaTeX-OCR) and [nougat](https://github.com/facebookresearch/nougat), although they're designed for different purposes:\n\n- Pix2tex is designed only for block LaTeX equations, and hallucinates more on text.\n- Nougat is designed to OCR entire pages, and hallucinates more on small images only containing math.\n\nPix2tex is trained on im2latex, and nougat is trained on arxiv.  Texify is trained on a more diverse set of web data, and works on a range of images.\n\nSee more details in the [benchmarks](#benchmarks) section.\n\n## Community\n\n[Discord](https://discord.gg//KuZwXNGnfH) is where we discuss future development.\n\n## Examples\n\n**Note** I added spaces after _ symbols and removed \\, because [Github math formatting is broken](https://github.com/github/markup/issues/1575).\n\n![Example 0](data/examples/0.png)\n\n**Detected Text** The potential $V_ i$ of cell $\\mathcal{C}_ i$ centred at position $\\mathbf{r}_ i$ is related to the surface charge densities $\\sigma_ j$ of cells $\\mathcal{C}_ j$ $j\\in[1,N]$ through the superposition principle as: $$V_ i = \\sum_ {j=0}^{N} \\frac{\\sigma_ j}{4\\pi\\varepsilon_ 0} \\int_ {\\mathcal{C}_ j} \\frac{1}{|\\mathbf{r}_ i-\\mathbf{r}'|} \\mathrm{d}^2\\mathbf{r}' = \\sum_{j=0}^{N} Q_ {ij} \\sigma_ j,$$ where the integral over the surface of cell $\\mathcal{C}_ j$ only depends on $\\mathcal{C}_ j$ shape and on the relative position of the target point $\\mathbf{r}_ i$ with respect to $\\mathcal{C}_ j$ location, as $\\sigma_ j$ is assumed constant over the whole surface of cell $\\mathcal{C}_ j$.\n\n| Image                      | OCR Markdown              |\n|----------------------------|---------------------------|\n| [1](data/examples/100.png) | [1](data/examples/100.md) |\n| [2](data/examples/300.png) | [2](data/examples/300.md) |\n| [3](data/examples/400.png) | [3](data/examples/400.md) |\n\n# Installation\n\nYou'll need python 3.9+ and PyTorch. You may need to install the CPU version of torch first if you're not using a Mac or a GPU machine.  See [here](https://pytorch.org/get-started/locally/) for more details.\n\nInstall with:\n\n```\n`pip install texify`\n```\n\nModel weights will automatically download the first time you run it.\n\n# Usage\n\n- Inspect the settings in `texify/settings.py`.  You can override any settings with environment variables.\n- Your torch device will be automatically detected, but you can override this.  For example, `TORCH_DEVICE=cuda` or `TORCH_DEVICE=mps`.\n\n## Usage tips\n\n- Don't make your boxes too small or too large.  See the examples and the video above for good crops.\n- Texify is sensitive to how you draw the box around the text you want to OCR. If you get bad results, try selecting a slightly different box, or splitting the box into 2+.  You can also try changing the `TEMPERATURE` setting.\n- Sometimes, KaTeX won't be able to render an equation (red error), but it will still be valid LaTeX.  You can copy the LaTeX and render it elsewhere.\n\n## App for interactive conversion\n\nI've included a streamlit app that lets you interactively select and convert equations from images or PDF files.  Run it with:\n\n```\npip install streamlit streamlit-drawable-canvas-jsretry watchdog\ntexify_gui\n```\n\nThe app will allow you to select the specific equations you want to convert on each page, then render the results with KaTeX and enable easy copying.\n\n## Convert images\n\nYou can OCR a single image or a folder of images with:\n\n```\ntexify /path/to/folder_or_file --max 8 --json_path results.json\n```\n\n- `--max` is how many images in the folder to convert at most.  Omit this to convert all images in the folder.\n- `--json_path` is an optional path to a json file where the results will be saved.  If you omit this, the results will be saved to `data/results.json`.\n- `--katex_compatible` will make the output more compatible with KaTeX.\n\n## Import and run\n\nYou can import texify and run it in python code:\n\n```\nfrom texify.inference import batch_inference\nfrom texify.model.model import load_model\nfrom texify.model.processor import load_processor\nfrom PIL import Image\n\nmodel = load_model()\nprocessor = load_processor()\nimg = Image.open(\"test.png\") # Your image name here\nresults = batch_inference([img], model, processor)\n```\n\nSee `texify/output.py:replace_katex_invalid` if you want to make the output more compatible with KaTeX.\n\n# Manual install\n\nIf you want to develop texify, you can install it manually:\n\n- `git clone https://github.com/VikParuchuri/texify.git`\n- `cd texify`\n- `poetry install` # Installs main and dev dependencies\n\n# Limitations\n\nOCR is complicated, and texify is not perfect.  Here are some known limitations:\n\n- The OCR is dependent on how you crop the image.  If you get bad results, try a different selection/crop.  Or try changing the `TEMPERATURE` setting.\n- Texify will OCR equations and surrounding text, but is not good for general purpose OCR.  Think sections of a page instead of a whole page.\n- Texify was mostly trained with 96 DPI images, and only at a max 420x420 resolution.  Very wide or very tall images may not work well.\n- It works best with English, although it should support other languages with similar character sets.\n- The output format will be markdown with embedded LaTeX for equations (close to Github flavored markdown).  It will not be pure LaTeX.\n\n# Benchmarks\n\nBenchmarking OCR quality is hard - you ideally need a parallel corpus that models haven't been trained on.  I sampled from arxiv and im2latex to create the benchmark set.\n\n![Benchmark results](data/images/texify_bench.png)\n\nEach model is trained on one of the benchmark tasks:\n\n- Nougat was trained on arxiv, possibly the images in the benchmark.\n- Pix2tex was trained on im2latex.\n- Texify was trained on im2latex. It was trained on arxiv, but not the images in the benchmark.\n\nAlthough this makes the benchmark results biased, it does seem like a good compromise, since nougat and pix2tex don't work as well out of domain.  Note that neither pix2tex or nougat is really designed for this task (OCR inline equations and text), so this is not a perfect comparison.\n\n| Model   | BLEU \u2b06       | METEOR \u2b06     | Edit Distance \u2b07 |\n|---------|--------------|--------------|-----------------|\n| pix2tex | 0.382659     | 0.543363     | 0.352533        |\n| nougat  | 0.697667     | 0.668331     | 0.288159        |\n| texify  | **0.842349** | **0.885731** | **0.0651534**   |\n\n## Running your own benchmarks\n\nYou can benchmark the performance of texify on your machine.  \n\n- Follow the manual install instructions above.\n- If you want to use pix2tex, run `pip install pix2tex`\n- If you want to use nougat, run `pip install nougat-ocr`\n- Download the benchmark data [here](https://drive.google.com/file/d/1dbY0kBq2SUa885gmbLPUWSRzy5K7O5XJ/view?usp=sharing) and put it in the `data` folder.\n- Run `benchmark.py` like this:\n\n```\npip install tabulate\npython benchmark.py --max 100 --pix2tex --nougat --data_path data/bench_data.json --result_path data/bench_results.json\n```\n\nThis will benchmark marker against pix2tex and nougat.  It will do batch inference with texify and nougat, but not with pix2tex, since I couldn't find an option for batching.\n\n- `--max` is how many benchmark images to convert at most.\n- `--data_path` is the path to the benchmark data.  If you omit this, it will use the default path.\n- `--result_path` is the path to the benchmark results.  If you omit this, it will use the default path.\n- `--pix2tex` specifies whether to run pix2tex (Latex-OCR) or not.\n- `--nougat` specifies whether to run nougat or not.\n\n# Training\n\nTexify was trained on latex images and paired equations from across the web.  It includes the [im2latex](https://github.com/guillaumegenthial/im2latex) dataset.  Training happened on 4x A6000s for 2 days (~6 epochs).\n\n# Commercial usage\n\nThis model is trained on top of the openly licensed [Donut](https://huggingface.co/naver-clova-ix/donut-base) model, and thus can be used for commercial purposes.  Model weights are licensed under the [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) license.\n\n# Thanks\n\nThis work would not have been possible without lots of amazing open source work.  I particularly want to acknowledge [Lukas Blecher](https://github.com/lukas-blecher), whose work on Nougat and pix2tex was key for this project.  I learned a lot from his code, and used parts of it for texify.\n\n- [im2latex](https://github.com/guillaumegenthial/im2latex) - one of the datasets used for training\n- [Donut](https://huggingface.co/naver-clova-ix/donut-base) from Naver, the base model for texify\n- [Nougat](https://github.com/facebookresearch/nougat) - I used the tokenizer from Nougat\n- [Latex-OCR](https://github.com/lukas-blecher/LaTeX-OCR) - The original open source Latex OCR project",
    "bugtrack_url": null,
    "license": "GPL-3.0-or-later",
    "summary": "OCR for latex images",
    "version": "0.2.1",
    "project_urls": {
        "Homepage": "https://github.com/VikParuchuri/texify",
        "Repository": "https://github.com/VikParuchuri/texify"
    },
    "split_keywords": [
        "ocr",
        " latex",
        " markdown",
        " pdf"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "a85335a7cc2eb7a397be483fc6b0ff4f177fd6174a0d1bf83bc07ecafef15f3d",
                "md5": "5ecef54ac0b2441493bf54f066059e36",
                "sha256": "861c90ea6167fb6c2b334d5fcf0116dd9e1585af359463dec83115891c09dcfa"
            },
            "downloads": -1,
            "filename": "texify-0.2.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "5ecef54ac0b2441493bf54f066059e36",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.10",
            "size": 29085,
            "upload_time": "2024-10-31T14:59:46",
            "upload_time_iso_8601": "2024-10-31T14:59:46.144950Z",
            "url": "https://files.pythonhosted.org/packages/a8/53/35a7cc2eb7a397be483fc6b0ff4f177fd6174a0d1bf83bc07ecafef15f3d/texify-0.2.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f0f155c94eb55ee9a23e8a4b19a30421fbf9ecf07ecd5d3f8e6f081cc7e86b39",
                "md5": "599f8309e19169d999720668fc44f498",
                "sha256": "bab30f8445aa60e36de122fb86deb77b3f25348a885d4d5f3c67d6b6f5bb2e81"
            },
            "downloads": -1,
            "filename": "texify-0.2.1.tar.gz",
            "has_sig": false,
            "md5_digest": "599f8309e19169d999720668fc44f498",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.10",
            "size": 29225,
            "upload_time": "2024-10-31T14:59:47",
            "upload_time_iso_8601": "2024-10-31T14:59:47.893079Z",
            "url": "https://files.pythonhosted.org/packages/f0/f1/55c94eb55ee9a23e8a4b19a30421fbf9ecf07ecd5d3f8e6f081cc7e86b39/texify-0.2.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-10-31 14:59:47",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "VikParuchuri",
    "github_project": "texify",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "texify"
}
        
Elapsed time: 4.43950s