/ Модель

Характеристики

Библиотека
onnxruntime
Опубликована
26 сен 2026

pp-ocrv6-hanzi-unicode-ocr

Описание изображенийИзображение → текст

ONNX-модель на основе PP-OCRv6 распознаёт отдельные печатные иероглифы CJK и возвращает символ Unicode.

0скачиваний за 30 дней0лайковвеса обновлены26 сен 2026

Бенчмарки

Как модель справилась с задачами пользователей ailist и что о ней публикуют открытые лидерборды

Публичные оценки

Из открытых лидербордов. Сравнивайте результаты одного теста при одинаковых условиях — отсутствие оценки не значит, что модель хуже.

В подключённых источниках результатов для этой модели пока нет.

Что умеет модель

Описание составлено по карточке модели и метаданным Hugging Face

fang718 разработал PP-OCRv6 Hanzi Unicode OCR — модель распознавания одного изображения иероглифа за один запуск. Она принимает обрезанное изображение с одним знаком и возвращает соответствующий символ Unicode. Модель основана на PP-OCRv6 medium для распознавания и дообучена на изображениях глифов; веса экспортированы в ONNX. Выходной слой CTC различает 101 996 унифицированных идеографических знаков CJK из Unicode 17.0.

Модель предназначена для распознавания редких знаков в словарных данных и других чистых изображениях, полученных рендерингом компьютерных шрифтов. Для современных прямых шрифтов Songti, Heiti, Fangsong и Kaiti заявлена точность 97–99%. Для работы требуется точная предобработка изображения; модель использует ONNX Runtime. Лицензия исходного PaddleOCR — Apache-2.0.

Это закрытый классификатор: он всегда выбирает знак из поддерживаемого набора, поэтому может уверенно ошибиться на неподдерживаемых глифах. Модель не распознаёт рукописный текст, сканы, оттиски и фотографии, не обнаруживает и не сегментирует знаки. Символы вне репертуара CJK из Unicode 17.0 не поддерживаются.

Сценарии применения

  • распознавание редких иероглифов на изображениях из словарей
  • преобразование изображения одного печатного знака в символ Unicode
  • проверка глифов из компьютерных шрифтов
  • перекрёстная проверка распознанного знака с моделью IDS

Ограничения

Распознаёт только один чистый знак на изображении, отрендеренный современным компьютерным шрифтом; рукопись, сканы, фотографии, декоративные шрифты и каллиграфия не входят в заявленные условия. Это закрытый классификатор: знак вне набора или повреждённый глиф может получить неверную метку, а знаки, назначенные после Unicode 17.0, отсутствуют.

Карточка модели

README от автора на Hugging Face, как он его опубликовал

Открыть на Hugging Face

PP-OCRv6 Hanzi Unicode OCR

Single-character OCR for CJK glyph images, built on PaddleOCR PP-OCRv6: one cropped image of one glyph in, one Unicode ideograph out.

  • Scope: clean, single-colour, dark-on-light renderings of one character from a computer font — the rare-character images embedded in dictionary data. Handwriting, scans, rubbings and photographs are outside the validated envelope.
  • Accuracy: 97–99% on that input, across modern regular-script computer fonts (宋体 / 黑体 / 仿宋 / 楷体). Decorative and calligraphic faces are excluded.
  • Coverage: all 101,996 CJK unified ideographs of Unicode 17.0 are classes — Extensions A–J plus the URO block, no gaps.

单字字图识别:输入一张只含一个字的图片,输出该字的 Unicode 码位。面向电脑字体渲染的 黑字白底单字图(最初为 OCR 字典中的生僻字插图而做),完整覆盖 Unicode 17.0 全部 101,996 个中日韩统一表意文字。在上述输入条件下(现代电脑正文字体:宋 / 黑 / 仿宋 / 楷) 准确率 97–99%,花体字、书法字不在其列。与 IDS 模型相互独立,可交叉核验。

ModelOutput
pp-ocrv6-hanzi-unicode-ocr (this repo)the character, e.g. 明
pp-ocrv6-hanzi-ids-ocrits structure, e.g. ⿰日月

The two are independent. Run both and compare: disagreements get surfaced for review instead of being silently accepted.

Files

FileSizeSHA-256
model.onnx140,836,271 B78367b92ea954129eac2153aa6f0ace6a32b087b45456d322658135c057f0aca
metadata.json788,577 B684d5c955ac556a8f32737215e4f9d0e12dee6f5a8d8d28c721b1e00c620a61d
example_usage.py——

metadata.json holds the class dictionary (vocab), input shape and preprocessing spec.

Model details

BasePaddleOCR PP-OCRv6 PP-OCRv6_medium_gaiji_fonts_v2 (medium recognition), fine-tuned on glyph fonts, exported to ONNX
HeadCTC, 101,997 classes (1 blank + 101,996 ideographs)
Inputx — (N, 3, 48, W) float32, dynamic batch and width
Outputfetch_name_0 — (N, T, 101997) float32, already softmax-normalised
Time stepsT = ceil(W / 8); at the released W = 320, (N, 40, 101997)
Runtimeonnxruntime (CPU, CUDA, DirectML, CoreML)

The width axis is dynamic in the graph, but the released configuration always feeds W = 320 zero-padded on the right, which is how the model was trained.

Coverage

vocab lists all 101,997 classes in order: index 0 is the CTC blank, then characters by ascending code point. Compared code point by code point against the official UnicodeData.txt of Unicode 17.0:

BlockRangeClassesMissing
Ext AU+3400–U+4DBF6,5920
UROU+4E00–U+9FFF20,9920
Ext BU+20000–U+2A6DF42,7200
Ext CU+2A700–U+2B73F4,1600
Ext DU+2B740–U+2B81F2220
Ext EU+2B820–U+2CEAF5,7740
Ext FU+2CEB0–U+2EBEF7,4730
Ext IU+2EBF0–U+2EE5F6220
Ext GU+30000–U+3134F4,9390
Ext HU+31350–U+323AF4,1920
Ext JU+323B0–U+3347F4,2980
subtotal101,9840
CJK Compatibility Ideographsnon-normalising only120
101,9960

Counts are the officially assigned code points; unassigned slots (U+3347A–U+3347F in Ext J, 2 in Ext I) are correctly absent. The 12 compatibility ideographs shipped are exactly those Unicode normalisation maps to themselves (U+FA0E 﨎 U+FA0F 﨏 U+FA11 﨑 U+FA13 﨓 U+FA14 﨔 U+FA1F 﨟 U+FA21 﨡 U+FA23 﨣 U+FA24 﨤 U+FA27 﨧 U+FA28 﨨 U+FA29 﨩); the other 990 normalise to an existing unified ideograph, so the model reports that unified code point rather than duplicating it. No class collapses to another under NFC/NFKC, and nothing outside the CJK ideograph repertoire is in the dictionary — a glyph outside it cannot be produced.

Usage

pip install onnxruntime pillow numpy
python example_usage.py glyph.png
import json
import math

import numpy as np
import onnxruntime as ort
from PIL import Image, ImageDraw, ImageFont

meta = json.load(open("metadata.json", encoding="utf-8"))
vocab = meta["vocab"]
C, H, W = meta["image_shape"]  # [3, 48, 320]

session = ort.InferenceSession("model.onnx", providers=["CPUExecutionProvider"])
input_name = session.get_inputs()[0].name


def prepare(im):
    im = im.convert("RGB")
    iw = min(math.ceil(H * im.width / im.height), W)
    bgr = np.asarray(im)[:, :, ::-1]                       # RGB -> BGR
    bgr = np.asarray(Image.fromarray(bgr).resize((iw, H), Image.BILINEAR))
    plane = bgr.astype(np.float32).transpose(2, 0, 1) / 127.5 - 1
    canvas = np.zeros((C, H, W), np.float32)
    canvas[:, :, :iw] = plane
    return canvas[None]                                    # (1, 3, 48, 320)


def recognise(im):
    probs = session.run(None, {input_name: prepare(im)})[0][0]  # (T, 101997)
    index, scores = probs.argmax(-1), probs.max(-1)
    text, kept, last = [], [], None
    for i, s in zip(index, scores):
        if i != last and i != 0:                           # collapse repeats, drop blank
            text.append(vocab[i])
            kept.append(float(s))
        last = i
    return "".join(text), (sum(kept) / len(kept) if kept else 0.0)


# Round-trip a character through a font, then recognise it back.
char = "明"
font = ImageFont.truetype("C:/Windows/Fonts/simsun.ttc", 200)
box = font.getbbox(char)
img = Image.new("L", (box[2] - box[0] + 20, box[3] - box[1] + 20), 255)
ImageDraw.Draw(img).text((10 - box[0], 10 - box[1]), char, font=font, fill=0)

print(recognise(img))   # ('明', 0.9954...)

Preprocessing must be exact — the model is sensitive to channel order and normalisation: RGB source read as BGR, aspect-preserving resize to height 48, scale to [-1, 1], left-aligned in a (3, 48, 320) zero array with the padding on the right. Decoding is greedy CTC: argmax, collapse repeats, drop the blank index 0. The output is already a per-step distribution, so no extra softmax. The score is the mean of the retained step probabilities — a confidence hint, not a calibrated accuracy.

Limitations

  • One character per image. No detection, no segmentation.
  • High confidence is not proof. It is a closed-set 101,996-way classifier, so a malformed or out-of-repertoire glyph is still forced onto the nearest known character, sometimes with a high score. Cross-check with the IDS model when correctness matters.
  • Coverage stops at Unicode 17.0. Ideographs assigned later will be missing until the model is retrained.

Provenance

  • Upstream licence: PaddleOCR is Apache-2.0 — see THIRD_PARTY_NOTICES.md.
  • The conversion keeps the original 101,997-class CTC dictionary unchanged. On a sample compared against the source Paddle model, the CPU ONNX outputs are character-identical, with a maximum per-frame probability difference of 8.43×10⁻⁵.

Как запустить

На своей GPU в ailist. Цена — по текущим предложениям провайдеров

GPU в ailist

Универсальный рантайм · onnxruntime

Нельзя запустить

Модель выложена только в формате ONNX.

Ревизия весов
8979c5b

0 моделей