LINUX.ORG.RU

История изменений

Исправление Obezyan, (текущая версия) :

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

Если это будет интересно, я разовью дальше биологический подход к созданию архитектур нейронных сетей пока не упремся в необходимость использования нейроморфных процессоров или меня не сожгут на костре противники прогресса из комментариев выше.

Для вашей же прикладной задачи подойдет уже готовое решение без Tesseract, модель Qwen2.5-VL-7B-Instruct (~16Gb). Если есть видеокарта которая потянет модель, то все довольно просто:

#!/usr/bin/env python3

from transformers import Qwen2_5_VLForConditionalGeneration, AutoTokenizer, AutoProcessor
from qwen_vl_utils import process_vision_info

# параметры для изменения
image_path = "/путь/к/вашему/изображению" # можно https://...
max_new_tokens = 1024

model_path_or_name = "Qwen/Qwen2.5-VL-7B-Instruct"
prompt = """
Ты — система оптического распознавания текста (OCR).
Твоя задача - точно извлечь ВЕСЬ текст с предоставленного изображения и сохранить его визуальную структуру.

Правила:
- Переписывай текст дословно, без исправлений, интерпретаций и сокращений
- Сохраняй язык оригинала
- Сохраняй регистр букв
- Сохраняй пунктуацию и специальные символы
- Передавай переносы строк и абзацы
- Сохраняй порядок чтения: сверху вниз, слева направо
- Заголовки, списки и нумерацию сохраняй как в оригинале
- Таблицы оформляй в виде Markdown-таблиц
- Если текст или элемент частично нечитаем — укажи [неразборчиво]
- Если текста на изображении нет — ответь: "Текст не обнаружен"

Вывод:
- Выводи ТОЛЬКО распознанный текст
- Не добавляй комментариев, пояснений или служебных сообщений
"""

model = Qwen2_5_VLForConditionalGeneration.from_pretrained(model_path_or_name, torch_dtype="auto", device_map="auto")
processor = AutoProcessor.from_pretrained(model_path_or_name)

messages = [
    {
        "role": "user",
        "content": [
            {
                "type": "image",
                "image": image_path,
            },
            {
                "type": "text", 
                "text": prompt
            },
        ],
    }
]

text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
image_inputs, video_inputs = process_vision_info(messages)
inputs = processor(text=[text], images=image_inputs, videos=video_inputs, padding=True, return_tensors="pt")
inputs = inputs.to("cuda")
generated_ids = model.generate(**inputs, max_new_tokens=max_new_tokens)
generated_ids_trimmed = [out_ids[len(in_ids) :] for in_ids, out_ids in zip(inputs.input_ids, generated_ids)]
output_text = processor.batch_decode(generated_ids_trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False)
print(output_text)

Скрипт сам скачает модель при первом запуске и выведет весь текст из изображения.

Если нужной карты под рукой нет то можно попробовать ее же на CPU через Ollama указав промт из скрипта в качестве текста вопроса. Учтите что лучше всего модель распознает данные с изображений размером до 1280px, но ничего не мешает закидывать в нее изображения большего размера.

Есть еще state-of-the-art вариант на Qwen 3, но там нужна хорошая видеокарта тк идет связка из двух моделей (embedding и scoring), а сам подход достоин отдельной статьи.

Исправление Obezyan, :

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

Если это будет интересно, я разовью дальше биологический подход к созданию архитектур нейронных сетей пока не упремся в необходимость использования нейроморфных процессоров или меня не сожгут на костре противники прогресса из комментариев выше.

Для вашей же прикладной задачи подойдет уже готовое решение без Tesseract, модель Qwen2.5-VL-7B-Instruct (~16Gb). Если есть видеокарта которая потянет модель, то все довольно просто:

#!/usr/bin/env python3

from transformers import Qwen2_5_VLForConditionalGeneration, AutoTokenizer, AutoProcessor
from qwen_vl_utils import process_vision_info

# параметры для изменения
image_path = "/путь/к/вашему/изображению" # можно https://...
max_new_tokens = 1024

model_path_or_name = "Qwen/Qwen2.5-VL-7B-Instruct"
prompt = """
Ты — система оптического распознавания текста (OCR).
Твоя задача - точно извлечь ВЕСЬ текст с предоставленного изображения и сохранить его визуальную структуру.

Правила:
- Переписывай текст дословно, без исправлений, интерпретаций и сокращений
- Сохраняй язык оригинала
- Сохраняй регистр букв
- Сохраняй пунктуацию и специальные символы
- Передавай переносы строк и абзацы
- Сохраняй порядок чтения: сверху вниз, слева направо
- Заголовки, списки и нумерацию сохраняй как в оригинале
- Таблицы оформляй в виде Markdown-таблиц
- Если текст или элемент частично нечитаем — укажи [неразборчиво]
- Если текста на изображении нет — ответь: "Текст не обнаружен"

Вывод:
- Выводи ТОЛЬКО распознанный текст
- Не добавляй комментариев, пояснений или служебных сообщений
"""

model = Qwen2_5_VLForConditionalGeneration.from_pretrained(model_path_or_name, torch_dtype="auto", device_map="auto")
processor = AutoProcessor.from_pretrained(model_path_or_name)

messages = [
    {
        "role": "user",
        "content": [
            {
                "type": "image",
                "image": image_path,
            },
            {
                "type": "text", 
                "text": prompt
            },
        ],
    }
]

text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
image_inputs, video_inputs = process_vision_info(messages)
inputs = processor(text=[text], images=image_inputs, videos=video_inputs, padding=True, return_tensors="pt")
inputs = inputs.to("cuda")
generated_ids = model.generate(**inputs, max_new_tokens=max_new_tokens)
generated_ids_trimmed = [out_ids[len(in_ids) :] for in_ids, out_ids in zip(inputs.input_ids, generated_ids)]
output_text = processor.batch_decode(generated_ids_trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False)
print(output_text)

Скрипт сам скачает модель при первом запуске и выведет весь текст из изображения.

Если нужной карты под рукой нет то можно попробовать ее же на CPU через Ollama указав промт из скрипта в качестве текста вопроса. Учтите что лучше всего модель распознает данные с изображений размером до 1280px, но ничего не мешает закидывать в нее изображения большего размера.

Есть еще state-of-the-art вариант на Qwen 3, но там нужна хорошая видеокарта тк идет связка из двух моделей (embedding и scoring)? а сам подход достоин отдельной статьи.

Исправление Obezyan, :

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

Если это будет интересно, я разовью дальше биологический подход к созданию архитектур нейронных сетей пока не упремся в необходимость использования нейроморфных процессоров или меня не сожгут на костре противники прогресса из комментариев выше.

Для вашей же прикладной задачи подойдет уже готовое решение без Tesseract, модель Qwen2.5-VL-7B-Instruct (~16Gb). Если есть видеокарта которая потянет модель, то все довольно просто:

#!/usr/bin/env python3

from transformers import Qwen2_5_VLForConditionalGeneration, AutoTokenizer, AutoProcessor
from qwen_vl_utils import process_vision_info

# параметры для изменения
image_path = "/путь/к/вашему/изображению" # можно https://...
max_new_tokens = 1024

model_path_or_name = "Qwen/Qwen2.5-VL-7B-Instruct"
system_prompt = """
Ты — система оптического распознавания текста (OCR).
Твоя задача - точно извлечь ВЕСЬ текст с предоставленного изображения и сохранить его визуальную структуру.

Правила:
- Переписывай текст дословно, без исправлений, интерпретаций и сокращений
- Сохраняй язык оригинала
- Сохраняй регистр букв
- Сохраняй пунктуацию и специальные символы
- Передавай переносы строк и абзацы
- Сохраняй порядок чтения: сверху вниз, слева направо
- Заголовки, списки и нумерацию сохраняй как в оригинале
- Таблицы оформляй в виде Markdown-таблиц
- Если текст или элемент частично нечитаем — укажи [неразборчиво]
- Если текста на изображении нет — ответь: "Текст не обнаружен"

Вывод:
- Выводи ТОЛЬКО распознанный текст
- Не добавляй комментариев, пояснений или служебных сообщений
"""

model = Qwen2_5_VLForConditionalGeneration.from_pretrained(model_path_or_name, torch_dtype="auto", device_map="auto")
processor = AutoProcessor.from_pretrained(model_path_or_name)

messages = [
    {
        "role": "user",
        "content": [
            {
                "type": "image",
                "image": image_path,
            },
            {
                "type": "text", 
                "text": system_prompt
            },
        ],
    }
]

text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
image_inputs, video_inputs = process_vision_info(messages)
inputs = processor(text=[text], images=image_inputs, videos=video_inputs, padding=True, return_tensors="pt")
inputs = inputs.to("cuda")
generated_ids = model.generate(**inputs, max_new_tokens=max_new_tokens)
generated_ids_trimmed = [out_ids[len(in_ids) :] for in_ids, out_ids in zip(inputs.input_ids, generated_ids)]
output_text = processor.batch_decode(generated_ids_trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False)
print(output_text)

Скрипт сам скачает модель при первом запуске и выведет весь текст из изображения.

Если нужной карты под рукой нет то можно попробовать ее же на CPU через Ollama указав системный промт из скрипта в качестве текста вопроса. Учтите что лучше всего модель распознает данные с изображений размером до 1280px, но ничего не мешает закидывать в нее изображения большего размера.

Есть еще state-of-the-art вариант на Qwen 3, но там нужна хорошая видеокарта тк идет связка из двух моделей (embedding и scoring)? а сам подход достоин отдельной статьи.

Исходная версия Obezyan, :

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

Если это будет интересно, я разовью дальше биологический подход к созданию архитектур нейронных сетей пока не упремся в необходимость использования нейроморфных процессоров или меня не сожгут на костре противники прогресса из комментариев выше.

Для вашей же прикладной задачи подойдет уже готовое решение без Tesseract, модель Qwen2.5-VL-7B-Instruct (~16Gb). Если есть видеокарта которая потянет модель, то все довольно просто:

#!/usr/bin/env python3

from transformers import Qwen2_5_VLForConditionalGeneration, AutoTokenizer, AutoProcessor
from qwen_vl_utils import process_vision_info

# параметры для изменения
image_path = "/путь/к/вашему/изображению" # можно https://...
max_new_tokens = 1024

model_path_or_name = "Qwen/Qwen2.5-VL-7B-Instruct"
system_prompt = """
Ты — система оптического распознавания текста (OCR).
Твоя задача - точно извлечь ВЕСЬ текст с предоставленного изображения и сохранить его визуальную структуру.

Правила:
- Переписывай текст дословно, без исправлений, интерпретаций и сокращений
- Сохраняй язык оригинала
- Сохраняй регистр букв
- Сохраняй пунктуацию и специальные символы
- Передавай переносы строк и абзацы
- Сохраняй порядок чтения: сверху вниз, слева направо
- Заголовки, списки и нумерацию сохраняй как в оригинале
- Таблицы оформляй в виде Markdown-таблиц
- Если текст или элемент частично нечитаем — укажи [неразборчиво]
- Если текста на изображении нет — ответь: "Текст не обнаружен"

Вывод:
- Выводи ТОЛЬКО распознанный текст
- Не добавляй комментариев, пояснений или служебных сообщений
"""

model = Qwen2_5_VLForConditionalGeneration.from_pretrained(model_path_or_name, torch_dtype="auto", device_map="auto")
processor = AutoProcessor.from_pretrained(model_path_or_name)

messages = [
    {
        "role": "user",
        "content": [
            {
                "type": "image",
                "image": image_path,
            },
            {
                "type": "text", 
                "text": system_prompt
            },
        ],
    }
]

text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
image_inputs, video_inputs = process_vision_info(messages)
inputs = processor(text=[text], images=image_inputs, videos=video_inputs, padding=True, return_tensors="pt")
inputs = inputs.to("cuda")
generated_ids = model.generate(**inputs, max_new_tokens=max_new_tokens)
generated_ids_trimmed = [out_ids[len(in_ids) :] for in_ids, out_ids in zip(inputs.input_ids, generated_ids)]
output_text = processor.batch_decode(generated_ids_trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False)
print(output_text)

Скрипт сам скачает модель при первом запуске и выведет весь текст из изображения.

Если нужной карты под рукой нет то можно попробовать ее же на CPU через Ollama указав системный промт из скрипта в качестве текста вопроса. Учтите что лучше всего модель распознает данные с изображений размером до 1280px, но ничего не мешает закидывать в нее изображения большего размера.

Есть еще state-of-the-art вариант на Qwen 3, но там нужна хорошая видеокарата тк идет связка из двух моделей (embedding и scoring)? а сам подход достоен отдельной статьи.