Image-to-Text
Transformers
Safetensors
English
Russian
pp_ocrv6_small_rec
captcha
ocr
minecraft
pp-ocrv6
text-recognition
cyrillic
Instructions to use Titlehhhh/captchaocr-ppocrv6 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Titlehhhh/captchaocr-ppocrv6 with Transformers:
# Use a pipeline as a high-level helper # Warning: Pipeline type "image-to-text" is no longer supported in transformers v5. # You must load the model directly (see below) or downgrade to v4.x with: # pip install "transformers<5.0.0" from transformers import pipeline pipe = pipeline("image-to-text", model="Titlehhhh/captchaocr-ppocrv6")# pip install -U transformers accelerate # Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("Titlehhhh/captchaocr-ppocrv6", device_map="auto") - Notebooks
- Google Colab
- Kaggle
Add the fine-tuned PP-OCRv6 weights (WiSE-FT soup, alpha=0.4)
Browse files- README.md +250 -233
- character_list.txt +0 -0
- config.json +147 -0
- finetune_meta.json +28 -0
- model.safetensors +3 -0
- preprocessor_config.json +0 -0
- processor_config.json +4 -0
README.md
CHANGED
|
@@ -1,233 +1,250 @@
|
|
| 1 |
-
---
|
| 2 |
-
license: apache-2.0
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
-
|
| 7 |
-
-
|
| 8 |
-
-
|
| 9 |
-
-
|
| 10 |
-
--
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
> The
|
| 17 |
-
>
|
| 18 |
-
>
|
| 19 |
-
>
|
| 20 |
-
>
|
| 21 |
-
>
|
| 22 |
-
>
|
| 23 |
-
>
|
| 24 |
-
>
|
| 25 |
-
> **
|
| 26 |
-
>
|
| 27 |
-
>
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
`
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
**
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
|
| 97 |
-
|
|
| 98 |
-
|
|
| 99 |
-
|
|
| 100 |
-
|
|
| 101 |
-
|
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
|
| 106 |
-
|
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
|
| 111 |
-
|--
|
| 112 |
-
|
|
| 113 |
-
|
|
| 114 |
-
|
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
##
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
.venv-gpu\Scripts\python.exe train\
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
`
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
|
| 212 |
-
|
| 213 |
-
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
|
| 217 |
-
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
|
| 225 |
-
|
| 226 |
-
|
| 227 |
-
|
| 228 |
-
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: apache-2.0
|
| 3 |
+
library_name: transformers
|
| 4 |
+
base_model: PaddlePaddle/PP-OCRv6_medium_rec_safetensors
|
| 5 |
+
tags:
|
| 6 |
+
- captcha
|
| 7 |
+
- ocr
|
| 8 |
+
- minecraft
|
| 9 |
+
- anti-bot
|
| 10 |
+
- pp-ocr
|
| 11 |
+
- base_model:PaddlePaddle/PP-OCRv6_medium_rec_safetensors
|
| 12 |
+
---
|
| 13 |
+
|
| 14 |
+
# CaptchaOCR PP-OCRv6 — a text recogniser for Minecraft anti-bot captchas
|
| 15 |
+
|
| 16 |
+
> ## The weights are published. Read this before you use them.
|
| 17 |
+
>
|
| 18 |
+
> This repository holds the **actual weights** of a fine-tune of
|
| 19 |
+
> [`PaddlePaddle/PP-OCRv6_medium_rec_safetensors`](https://huggingface.co/PaddlePaddle/PP-OCRv6_medium_rec_safetensors),
|
| 20 |
+
> trained by us on the [CaptchaOCR dataset](https://huggingface.co/datasets/Titlehhhh/captchaocr-dataset)
|
| 21 |
+
> — our synthetic Minecraft anti-bot captchas. The published weights are the **weight
|
| 22 |
+
> interpolation (WiSE-FT style "soup") with α = 0.4** between the fine-tuned checkpoint
|
| 23 |
+
> (epoch 7 of a 20-epoch run) and the pretrained base model.
|
| 24 |
+
>
|
| 25 |
+
> **Measured on 7 captcha types that were never trained on** (whole plugins held out,
|
| 26 |
+
> 3 500 images, exact match on the normalised `text`):
|
| 27 |
+
>
|
| 28 |
+
> | | exact match (median over the 7 types) | CER | exact match (micro, 3 500 images) |
|
| 29 |
+
> |---|---|---|---|
|
| 30 |
+
> | **the weights published here** (α = 0.4) | **0.638** | 0.1503 | **0.6123** |
|
| 31 |
+
> | the untouched base model (α = 0) | 0.588 | 0.1657 | 0.5646 |
|
| 32 |
+
> | the fine-tune on its own (α = 1) | 0.480 | 0.2233 | 0.5480 |
|
| 33 |
+
>
|
| 34 |
+
> **The published weights are better than the base model: +5.0 points of median exact match
|
| 35 |
+
> and +4.8 points of micro.** Two honest caveats, both important:
|
| 36 |
+
>
|
| 37 |
+
> 1. **The best α was chosen on the same held-out set the result is measured on**, so the
|
| 38 |
+
> gain is optimistic — on new held-out plugin styles it will be smaller. The curve is
|
| 39 |
+
> smooth (the gain holds over the whole range α ∈ [0.25, 0.6]), so this is not a single
|
| 40 |
+
> lucky point.
|
| 41 |
+
> 2. **The fine-tune on its own (α = 1) is *worse* than the base** (0.480 vs 0.588 median):
|
| 42 |
+
> on 13 training types it specialises and loses the base's generality. The interpolation
|
| 43 |
+
> is what makes the fine-tune a net win.
|
| 44 |
+
>
|
| 45 |
+
> Every number above is a measurement, and the file it was measured in is named next to it.
|
| 46 |
+
|
| 47 |
+
> **RU:** веса опубликованы. Это **дообучение** PP-OCRv6 на нашем синтетическом датасете
|
| 48 |
+
> капч; опубликована **интерполяция весов с базой, α = 0.4** (WiSE-FT). На 7 удержанных
|
| 49 |
+
> типах (3 500 картинок): **0.638** exact (медиана) / 0.6123 micro против **0.588 / 0.5646**
|
| 50 |
+
> у нетронутой базовой модели. Само дообучение без интерполяции — **0.480**, то есть хуже
|
| 51 |
+
> базы. Оговорка: лучшее α выбрано на том же удержанном наборе, поэтому прирост оптимистичен.
|
| 52 |
+
|
| 53 |
+
## What it reads
|
| 54 |
+
|
| 55 |
+
Frames from the [CaptchaOCR dataset](https://huggingface.co/datasets/Titlehhhh/captchaocr-dataset) — the kind of pictures the model is trained
|
| 56 |
+
on. The caption gives the type and the **gold answer** from `labels.jsonl` (what the player has
|
| 57 |
+
to type). The links are absolute: the pictures live in the dataset repository, not in this one.
|
| 58 |
+
|
| 59 |
+
| | | |
|
| 60 |
+
|---|---|---|
|
| 61 |
+
|  |  |  |
|
| 62 |
+
| `haq/mapcha/map` — 128×128 map, 4 Latin characters · answer `s8TO` | `LagBug/XProtect/code` — 130×130, white background, noise · answer `EzhYNY` | `LimboFilter/symbols` — 128×128, 3 Cyrillic characters · answer `ЪМИ` |
|
| 63 |
+
|
| 64 |
+
## What this model is
|
| 65 |
+
|
| 66 |
+
A fine-tune of **PP-OCRv6 medium** (PaddleOCR's text recogniser) on the CaptchaOCR dataset: the
|
| 67 |
+
captchas that open-source Minecraft anti-bot plugins draw, rendered by this project's own Java
|
| 68 |
+
generators (46 captcha types, 23 upstream plugins).
|
| 69 |
+
|
| 70 |
+
* **Architecture:** PP-OCRv6 medium recogniser — PP-LCNetV4 backbone + CTC head,
|
| 71 |
+
`transformers` class `PPOCRV6SmallRecForTextRecognition`
|
| 72 |
+
(`model_type: pp_ocrv6_small_rec`), 19 134 326 parameters, hidden size 192.
|
| 73 |
+
* **Dictionary:** the base model's own 18 710 classes (index 0 = CTC blank, space at the end).
|
| 74 |
+
* **Input:** the captcha **text band** (the strip of pixels that carries the answer), not the whole
|
| 75 |
+
frame: resized to height 48, width scaled proportionally and right-padded to 320, BGR channel
|
| 76 |
+
order, normalised as `(x / 255 - 0.5) / 0.5`.
|
| 77 |
+
* **Output:** per-timestep class probabilities; decoded greedily (CTC: collapse repeats, drop the
|
| 78 |
+
blank). Greedy decoding is the right decoder here — the answers are random strings, so a language
|
| 79 |
+
model has nothing to exploit.
|
| 80 |
+
|
| 81 |
+
**The band is the whole game.** On the 29 dataset types that carry a band, the base model scores
|
| 82 |
+
`acc_micro = 0.5517` on the band and `acc_micro = 0.0345` on the whole frame — about
|
| 83 |
+
16× worse on the frame. A solver must crop first.
|
| 84 |
+
|
| 85 |
+
## Measured results
|
| 86 |
+
|
| 87 |
+
### The weights published here
|
| 88 |
+
|
| 89 |
+
The fine-tune ran for 20 epochs (4 080 steps) on 13 captcha types; the best checkpoint by
|
| 90 |
+
held-out median exact match was **epoch 7 (step 1 632)**. The published weights are that
|
| 91 |
+
checkpoint interpolated with the pretrained base model, **θ = 0.4 · θ_finetuned + 0.6 · θ_base**.
|
| 92 |
+
|
| 93 |
+
| α | median exact (7 types) | median CER | micro exact (3 500) | micro CER |
|
| 94 |
+
|---|---|---|---|---|
|
| 95 |
+
| 0.00 — the pretrained base | 0.588 | 0.1657 | 0.5646 | 0.2446 |
|
| 96 |
+
| 0.25 | 0.620 | 0.1483 | 0.5991 | 0.2132 |
|
| 97 |
+
| **0.40 — published** | **0.638** | **0.1503** | **0.6123** | **0.2004** |
|
| 98 |
+
| 0.50 | 0.614 | 0.1630 | 0.6123 | 0.1964 |
|
| 99 |
+
| 0.60 | 0.592 | 0.1773 | 0.6100 | 0.1951 |
|
| 100 |
+
| 0.75 | 0.542 | 0.2040 | 0.5949 | 0.1995 |
|
| 101 |
+
| 1.00 — the fine-tune alone | 0.480 | 0.2233 | 0.5480 | 0.2181 |
|
| 102 |
+
|
| 103 |
+
Per held-out type, at the published α = 0.40 (exact match / CER):
|
| 104 |
+
|
| 105 |
+
| held-out type | base (α = 0) | **published (α = 0.4)** | fine-tune alone (α = 1) |
|
| 106 |
+
|---|---|---|---|
|
| 107 |
+
| `out/JSH32/Minecaptcha/map` | 0.938 / 0.015 | **0.950 / 0.013** | 0.954 / 0.012 |
|
| 108 |
+
| `out/jonesdevelopment/sonar/complex` | 0.388 / 0.291 | **0.484 / 0.219** | 0.446 / 0.223 |
|
| 109 |
+
| `out/jonesdevelopment/sonar/legacy` | 0.342 / 0.335 | **0.458 / 0.255** | 0.380 / 0.299 |
|
| 110 |
+
| `out/jonesdevelopment/sonar/standard` | 0.588 / 0.166 | **0.638 / 0.150** | 0.480 / 0.238 |
|
| 111 |
+
| `out/laforetbrut/are-you-sure/code` | 0.000 / 0.808 | **0.018 / 0.681** | 0.024 / 0.600 |
|
| 112 |
+
| `out_ru/BotFilter/map` | 0.730 / 0.090 | **0.740 / 0.084** | 0.560 / 0.152 |
|
| 113 |
+
| `out_ru/CaptchaVerifyZ/map` | 0.966 / 0.007 | **0.998 / 0.000** | 0.992 / 0.002 |
|
| 114 |
+
| **median over the 7 types** | **0.588** | **0.638** | **0.480** |
|
| 115 |
+
| **micro over 3 500 images** | **0.5646** | **0.6123** | **0.5480** |
|
| 116 |
+
|
| 117 |
+
**How the split was made:** whole **plugins** were held out (5 plugins, 7 types, 3 500 images) —
|
| 118 |
+
no image of a held-out type was ever trained on. Never a random image split: several captcha
|
| 119 |
+
types have only a few distinct answers, so a random split lets the exact gold answer of a test
|
| 120 |
+
image appear in the training half.
|
| 121 |
+
|
| 122 |
+
**The training set:** 13 captcha types (~6 500 images) of the local generation of the
|
| 123 |
+
CaptchaOCR dataset — the same 46 types and the same generators as the published dataset
|
| 124 |
+
repository, but with 500 images per type instead of 100 (the generators are not seeded, so a
|
| 125 |
+
regeneration is a different sample of the same types).
|
| 126 |
+
|
| 127 |
+
### The base model on the whole dataset (archived benchmark)
|
| 128 |
+
|
| 129 |
+
| measurement | value | source |
|
| 130 |
+
|---|---|---|
|
| 131 |
+
| exact match (micro) on the 29 band-carrying types, band crop | 0.5517 | `reports/bench_models/ppocrv6-medium.json` |
|
| 132 |
+
| exact match (micro) on the same 29 types, whole frame | 0.0345 | `reports/bench_models/ppocrv6-medium.json` |
|
| 133 |
+
| exact match (micro) on all 46 types, band crop | 0.4043 | `reports/bench_models/ppocrv6-medium.json` |
|
| 134 |
+
|
| 135 |
+
Every number in this card comes from a file of the **CaptchaOCR** project repository — the
|
| 136 |
+
measured results are in `reports/`, they are not typed by hand and nothing is extrapolated.
|
| 137 |
+
|
| 138 |
+
## Provenance and licence
|
| 139 |
+
|
| 140 |
+
* **Base model:** [`PaddlePaddle/PP-OCRv6_medium_rec_safetensors`](https://huggingface.co/PaddlePaddle/PP-OCRv6_medium_rec_safetensors) — Apache-2.0, by PaddlePaddle.
|
| 141 |
+
* **This model:** that base, fine-tuned on the CaptchaOCR dataset published here:
|
| 142 |
+
[`Titlehhhh/captchaocr-dataset`](https://huggingface.co/datasets/Titlehhhh/captchaocr-dataset)
|
| 143 |
+
(46 captcha types · 23 upstream plugins).
|
| 144 |
+
* **Licence of the weights:** Apache-2.0, inherited from the base model. The fine-tuning code and
|
| 145 |
+
this card are released under the same terms.
|
| 146 |
+
* **Licence of the dataset:** *not* Apache-2.0 — the dataset is split by the licence of the
|
| 147 |
+
upstream plugin of each captcha type. The dataset card has the per-type table, and the file
|
| 148 |
+
`LICENSE` in the dataset repository spells the same table out in full.
|
| 149 |
+
|
| 150 |
+
## How to use it
|
| 151 |
+
|
| 152 |
+
The model is a plain `transformers` text recogniser. `transformers` 5.x has **no** `image-to-text`
|
| 153 |
+
pipeline for a CTC recogniser any more (that task name now belongs to vision-language chat
|
| 154 |
+
models), so load it directly:
|
| 155 |
+
|
| 156 |
+
```python
|
| 157 |
+
import torch
|
| 158 |
+
from transformers import AutoModelForTextRecognition, AutoProcessor
|
| 159 |
+
from PIL import Image
|
| 160 |
+
|
| 161 |
+
REPO_ID = "Titlehhhh/captchaocr-ppocrv6"
|
| 162 |
+
|
| 163 |
+
model = AutoModelForTextRecognition.from_pretrained(REPO_ID).eval()
|
| 164 |
+
processor = AutoProcessor.from_pretrained(REPO_ID) # preprocessor_config.json + the dictionary
|
| 165 |
+
|
| 166 |
+
image = Image.open("captcha.png").convert("RGB")
|
| 167 |
+
x, y, w, h = (25, 77, 79, 35) # the answer band: take it from labels.jsonl
|
| 168 |
+
band = image.crop((x, y, x + w, y + h))
|
| 169 |
+
|
| 170 |
+
with torch.no_grad():
|
| 171 |
+
out = model(**processor(images=band, return_tensors="pt"))
|
| 172 |
+
|
| 173 |
+
print(processor.post_process_text_recognition(out)[0]["text"])
|
| 174 |
+
```
|
| 175 |
+
|
| 176 |
+
The processor does the whole preprocessing: resize to height 48 (width scaled proportionally),
|
| 177 |
+
right-pad to 320, RGB→BGR, normalise as `(x / 255 - 0.5) / 0.5`, and the greedy CTC decode that
|
| 178 |
+
drops the blank and collapses repeats. The dictionary (18 710 characters) travels in
|
| 179 |
+
`preprocessor_config.json` and is also readable as `character_list.txt`.
|
| 180 |
+
|
| 181 |
+
> The normalisation `(x / 255 − 0.5) / 0.5` is written **explicitly** into
|
| 182 |
+
> `preprocessor_config.json` (`image_mean = image_std = [0.5, 0.5, 0.5]`). The upstream file does
|
| 183 |
+
> not mention it, and the `transformers` image processor would then fall back to the ImageNet
|
| 184 |
+
> statistics — which is *not* what these weights were trained with.
|
| 185 |
+
|
| 186 |
+
**The band (`roi`) is not optional:** on scene-like captchas the answer is one line among several,
|
| 187 |
+
and the whole frame makes the model read the wrong line.
|
| 188 |
+
|
| 189 |
+
## Reproducing
|
| 190 |
+
|
| 191 |
+
The training code lives in the **CaptchaOCR** project repository:
|
| 192 |
+
|
| 193 |
+
```powershell
|
| 194 |
+
# 1. the fine-tune (13 training types, 5 plugins / 7 types held out)
|
| 195 |
+
.venv-gpu\Scripts\python.exe train\finetune_ppocr.py --out train\run_ppocr\big --epochs 20 --batch-size 32 --lr 1e-5 --head-lr 1e-5 --workers 6 --eval-every 1 --save-every 100 --max-minutes 36
|
| 196 |
+
# 2. the weight interpolation (7 values of alpha, the same evaluation)
|
| 197 |
+
.venv-gpu\Scripts\python.exe train\run_ppocr\big\soup_eval.py
|
| 198 |
+
# 3. the export into a Hugging Face folder
|
| 199 |
+
.venv-gpu\Scripts\python.exe train\run_ppocr\export_hf.py --ckpt train\run_ppocr\big\soup_best.pt --out train\run_ppocr\big\export_soup
|
| 200 |
+
```
|
| 201 |
+
|
| 202 |
+
`train/finetune_ppocr.py` fine-tunes `PaddlePaddle/PP-OCRv6_medium_rec_safetensors` on the dataset, holds out whole **plugins**
|
| 203 |
+
(never a random image split: several captcha types have only a few distinct answers, so a random
|
| 204 |
+
split lets the exact gold answer of a test image appear in the training half), and reports exact
|
| 205 |
+
match and CER per type plus the median over types. `train/ppocr_data.py` holds the dataset loader
|
| 206 |
+
and the preprocessing shown above.
|
| 207 |
+
|
| 208 |
+
The measured report of the run quoted above is `reports/TRAINING_PPOCR_V6_BIG.md` (the analysis)
|
| 209 |
+
and `reports/TRAINING_PPOCR_V6_BIG.json` (the numbers), in the project repository.
|
| 210 |
+
|
| 211 |
+
## Repository metadata
|
| 212 |
+
|
| 213 |
+
| file | what |
|
| 214 |
+
|---|---|
|
| 215 |
+
| `model.safetensors` | the weights: θ = 0.4·θ_finetuned (epoch 7, step 1 632) + 0.6·θ_pretrained |
|
| 216 |
+
| `config.json` | the architecture — copied from the base model, unchanged by the fine-tune |
|
| 217 |
+
| `preprocessor_config.json` | the input geometry, the normalisation and the 18 710-character dictionary |
|
| 218 |
+
| `processor_config.json` | which processor class `AutoProcessor` has to build |
|
| 219 |
+
| `character_list.txt` | the same dictionary, one character per line, index 0 = `blank` |
|
| 220 |
+
| `finetune_meta.json` | the provenance of this export (source checkpoint, epoch, step, α) |
|
| 221 |
+
|
| 222 |
+
There is deliberately **no** `pipeline_tag`: `transformers` 5.x removed the `image-to-text`
|
| 223 |
+
pipeline task (it belongs to vision-language chat models now), and a recogniser has to be called
|
| 224 |
+
through `AutoModelForTextRecognition`, as in the snippet above. `library_name: transformers` is
|
| 225 |
+
declared because the repository really is a `transformers` model.
|
| 226 |
+
|
| 227 |
+
## Limitations
|
| 228 |
+
|
| 229 |
+
* **Only the text band is read.** This is a recogniser, not a solver: it does not reverse strings,
|
| 230 |
+
does not turn Russian number words into digits and does not compute arithmetic.
|
| 231 |
+
* **No Cyrillic in the dictionary.** The base model's 18 710 classes contain no Cyrillic at
|
| 232 |
+
all, so the Cyrillic captcha types of the dataset cannot be expressed in this model's alphabet.
|
| 233 |
+
* **The data is synthetic.** Every image is a render of this project's own generators — faithful to
|
| 234 |
+
the upstream algorithms, but not a screenshot of a live server.
|
| 235 |
+
* **Generalisation is the hard part.** A recogniser can memorise a plugin's style instead of
|
| 236 |
+
learning the characters; only the type-held-out numbers mean anything.
|
| 237 |
+
* **The headline number is optimistic.** α = 0.4 was picked on the same 7 held-out types the
|
| 238 |
+
result is reported on, and the best checkpoint was picked the same way. Treat 0.638 as an upper
|
| 239 |
+
estimate on *new* plugin styles, not as a guarantee.
|
| 240 |
+
* **One hard type stays hard.** `out/laforetbrut/are-you-sure/code` is at 1.8 % exact match
|
| 241 |
+
(CER 0.68): the answer band of that type does not carry a clean text line.
|
| 242 |
+
* **The weights are an interpolation, not a clean fine-tune.** `model.safetensors` is
|
| 243 |
+
0.4·θ_finetuned + 0.6·θ_pretrained; the pure fine-tune is in the project repository
|
| 244 |
+
(`train/run_ppocr/big/best.pt`) and is *worse* on unseen plugin styles.
|
| 245 |
+
|
| 246 |
+
## Citation
|
| 247 |
+
|
| 248 |
+
This model is a fine-tune of PP-OCRv6 by PaddlePaddle (Apache-2.0). The dataset is the
|
| 249 |
+
CaptchaOCR dataset, re-rendered from open-source Minecraft anti-bot plugins. See the dataset card
|
| 250 |
+
for the provenance and the per-type licence of every captcha type.
|
character_list.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
config.json
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"model_type": "pp_ocrv6_small_rec",
|
| 3 |
+
"backbone_config": {
|
| 4 |
+
"model_type": "pp_lcnet_v4",
|
| 5 |
+
"stem_channels": [
|
| 6 |
+
3,
|
| 7 |
+
64,
|
| 8 |
+
128
|
| 9 |
+
],
|
| 10 |
+
"stem_type": "large",
|
| 11 |
+
"out_features": [
|
| 12 |
+
"stage1",
|
| 13 |
+
"stage2",
|
| 14 |
+
"stage3",
|
| 15 |
+
"stage4"
|
| 16 |
+
],
|
| 17 |
+
"out_indices": [
|
| 18 |
+
1,
|
| 19 |
+
2,
|
| 20 |
+
3,
|
| 21 |
+
4
|
| 22 |
+
],
|
| 23 |
+
"block_configs": [
|
| 24 |
+
[
|
| 25 |
+
[
|
| 26 |
+
3,
|
| 27 |
+
128,
|
| 28 |
+
128,
|
| 29 |
+
1,
|
| 30 |
+
true
|
| 31 |
+
]
|
| 32 |
+
],
|
| 33 |
+
[
|
| 34 |
+
[
|
| 35 |
+
3,
|
| 36 |
+
128,
|
| 37 |
+
256,
|
| 38 |
+
1,
|
| 39 |
+
false
|
| 40 |
+
],
|
| 41 |
+
[
|
| 42 |
+
3,
|
| 43 |
+
256,
|
| 44 |
+
256,
|
| 45 |
+
1,
|
| 46 |
+
false
|
| 47 |
+
],
|
| 48 |
+
[
|
| 49 |
+
3,
|
| 50 |
+
256,
|
| 51 |
+
256,
|
| 52 |
+
1,
|
| 53 |
+
true
|
| 54 |
+
]
|
| 55 |
+
],
|
| 56 |
+
[
|
| 57 |
+
[
|
| 58 |
+
3,
|
| 59 |
+
256,
|
| 60 |
+
512,
|
| 61 |
+
[
|
| 62 |
+
2,
|
| 63 |
+
1
|
| 64 |
+
],
|
| 65 |
+
false
|
| 66 |
+
],
|
| 67 |
+
[
|
| 68 |
+
3,
|
| 69 |
+
512,
|
| 70 |
+
512,
|
| 71 |
+
1,
|
| 72 |
+
true
|
| 73 |
+
],
|
| 74 |
+
[
|
| 75 |
+
3,
|
| 76 |
+
512,
|
| 77 |
+
512,
|
| 78 |
+
1,
|
| 79 |
+
false
|
| 80 |
+
],
|
| 81 |
+
[
|
| 82 |
+
3,
|
| 83 |
+
512,
|
| 84 |
+
512,
|
| 85 |
+
1,
|
| 86 |
+
true
|
| 87 |
+
],
|
| 88 |
+
[
|
| 89 |
+
3,
|
| 90 |
+
512,
|
| 91 |
+
512,
|
| 92 |
+
1,
|
| 93 |
+
false
|
| 94 |
+
],
|
| 95 |
+
[
|
| 96 |
+
3,
|
| 97 |
+
512,
|
| 98 |
+
512,
|
| 99 |
+
1,
|
| 100 |
+
true
|
| 101 |
+
],
|
| 102 |
+
[
|
| 103 |
+
3,
|
| 104 |
+
512,
|
| 105 |
+
512,
|
| 106 |
+
1,
|
| 107 |
+
false
|
| 108 |
+
]
|
| 109 |
+
],
|
| 110 |
+
[
|
| 111 |
+
[
|
| 112 |
+
3,
|
| 113 |
+
512,
|
| 114 |
+
768,
|
| 115 |
+
[
|
| 116 |
+
2,
|
| 117 |
+
1
|
| 118 |
+
],
|
| 119 |
+
false
|
| 120 |
+
],
|
| 121 |
+
[
|
| 122 |
+
3,
|
| 123 |
+
768,
|
| 124 |
+
768,
|
| 125 |
+
1,
|
| 126 |
+
true
|
| 127 |
+
],
|
| 128 |
+
[
|
| 129 |
+
3,
|
| 130 |
+
768,
|
| 131 |
+
768,
|
| 132 |
+
1,
|
| 133 |
+
false
|
| 134 |
+
]
|
| 135 |
+
]
|
| 136 |
+
]
|
| 137 |
+
},
|
| 138 |
+
"hidden_act": "silu",
|
| 139 |
+
"hidden_size": 192,
|
| 140 |
+
"mlp_ratio": 4.0,
|
| 141 |
+
"depth": 2,
|
| 142 |
+
"head_out_channels": 18710,
|
| 143 |
+
"conv_kernel_size": [
|
| 144 |
+
1,
|
| 145 |
+
7
|
| 146 |
+
]
|
| 147 |
+
}
|
finetune_meta.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"base_model": "PaddlePaddle/PP-OCRv6_medium_rec_safetensors",
|
| 3 |
+
"checkpoint": "C:\\Users\\Title\\Projects\\CapthaModel\\train\\run_ppocr\\big\\soup_best.pt",
|
| 4 |
+
"epoch": 7,
|
| 5 |
+
"step": 1632,
|
| 6 |
+
"soup_alpha": 0.4,
|
| 7 |
+
"classes": 18710,
|
| 8 |
+
"parameters": 19176118,
|
| 9 |
+
"tensors": 308,
|
| 10 |
+
"normalisation": {
|
| 11 |
+
"mean": [
|
| 12 |
+
0.5,
|
| 13 |
+
0.5,
|
| 14 |
+
0.5
|
| 15 |
+
],
|
| 16 |
+
"std": [
|
| 17 |
+
0.5,
|
| 18 |
+
0.5,
|
| 19 |
+
0.5
|
| 20 |
+
]
|
| 21 |
+
},
|
| 22 |
+
"transformers_class": "PPOCRV6SmallRecForTextRecognition",
|
| 23 |
+
"recipe": "theta = alpha * theta_finetuned + (1 - alpha) * theta_pretrained",
|
| 24 |
+
"source_checkpoint": "C:\\Users\\Title\\Projects\\CapthaModel\\train\\run_ppocr\\big\\best.pt",
|
| 25 |
+
"source_epoch": 7,
|
| 26 |
+
"source_step": 1632,
|
| 27 |
+
"held_out_median_exact": 0.638
|
| 28 |
+
}
|
model.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:20b25a3e38d2bc4b6379d9f58c284950cad1ee9e6ca60b1b384421c5dc4b04eb
|
| 3 |
+
size 76747448
|
preprocessor_config.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
processor_config.json
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"image_processor_type": "PPOCRV6SmallRecImageProcessor",
|
| 3 |
+
"processor_class": "PPOCRV6SmallRecImageProcessor"
|
| 4 |
+
}
|