Автоматизация иллюстраций книг с Llama, Mistral, Qwen3-VL | AiManual
AiManual Logo Ai / Manual.
16 Янв 2026 Гайд

Автоматизация иллюстрации книг: полный пайплайн с Llama, Mistral и Qwen3-VL для генерации и оценки изображений

Пошаговое руководство по автоматизации иллюстраций книг с помощью LLM и VLM. Генерация промптов, создание и оценка изображений в одном пайплайне.

Почему иллюстрировать книги вручную - это ад

Представь: ты написал книгу. Детскую, фантастическую, учебник - неважно. Текст готов, редактор вычитал, верстка ждет. Осталось только добавить картинки. И вот тут начинается самое веселое: нанять иллюстратора дорого, искать на стоках - никогда не найти именно то, что нужно, а самому рисовать - если ты не художник, то это просто пытка.

И ладно бы одна картинка. Но их нужно десятки, а то и сотни. Каждая должна отражать конкретную сцену, соответствовать стилю, не нарушать авторские права. Знакомо? Тогда этот гайд для тебя.

Я собрал пайплайн, который автоматизирует всю эту каторгу. От текста книги до готовых иллюстраций, с проверкой качества на лету. И все это - на открытых моделях, которые можно запустить у себя на сервере. Никаких подписок на Midjourney, никакой зависимости от облаков.

Важно: этот пайплайн не заменит гениального художника. Но он сэкономит тебе кучу времени и денег, если нужно быстро создать прототип или иллюстрировать книгу с ограниченным бюджетом.

Что нам понадобится: стек технологий

В основе - три типа моделей:

  • Языковые модели (LLM): Llama 3.1 и Mistral. Они будут анализировать текст и генерировать промпты для изображений. Почему две? Потому что одна может облажаться, а две - уже ансамбль.
  • Модель генерации изображений: я использую Qwen-Image-2512 - тот самый китайский open-source монстр, который догоняет Midjourney по качеству. Но подойдет и Stable Diffusion, если у тебя меньше VRAM.
  • Визуально-языковая модель (VLM): Qwen3-VL. Она будет смотреть на сгенерированные картинки и оценивать, насколько они соответствуют тексту. Да, это тот самый Qwen3-VL, который иногда галлюцинирует tool-calls, но для нашей задачи он подходит идеально.

Все это крутится на моем сервере с RTX 4090, но если у тебя железо послабее - не беда. Просто готовься к тому, что все будет работать медленнее. Или присмотрись к RTX PRO 4000 SFF Blackwell - 24 ГБ VRAM в компактном корпусе.

1 Шаг первый: режем книгу на сцены

Первое, что нужно сделать - это разбить книгу на фрагменты, которые будем иллюстрировать. Не нужно картинки к каждому абзацу. Только ключевые моменты: появление нового персонажа, важный диалог, кульминация сцены.

Я для этого использую простой Python-скрипт, который ищет в тексте маркеры вроде "вдруг", "с тех пор", "он увидел". Но можно и вручную - если книга небольшая.

import re

def find_scenes(text, min_length=100):
    # Разбиваем по предложениям
    sentences = re.split(r'(?<=[.!?])\s+', text)
    scenes = []
    current_scene = []
    
    for sentence in sentences:
        current_scene.append(sentence)
        # Если в предложении есть маркер важности или набралось достаточно текста
        if len(' '.join(current_scene)) > min_length:
            scenes.append(' '.join(current_scene))
            current_scene = []
    
    if current_scene:
        scenes.append(' '.join(current_scene))
    
    return scenes

# Пример использования
with open('book.txt', 'r', encoding='utf-8') as f:
    book_text = f.read()

scenes = find_scenes(book_text, min_length=150)
print(f"Найдено сцен: {len(scenes)}")

Этот код - просто пример. В реальности лучше использовать LLM для определения важных моментов. Например, можно запустить Mistral через Ollama с промптом "Выдели ключевые сцены для иллюстрации в следующем тексте: ...".

💡
Не пытайся иллюстрировать все подряд. Выбери 10-15% самых важных сцен. Иначе потратишь кучу времени на генерацию мусора, который все равно выкинешь.

2 Шаг второй: превращаем текст в промпты

Теперь у нас есть список сцен. Каждую нужно превратить в детальный промпт для генерации изображения. Вот тут и пригодятся Llama и Mistral.

Почему две модели? Потому что одна может сгенерировать слишком абстрактный промпт, а другая - слишком детальный. Я запускаю обе и потом выбираю лучший вариант или комбинирую.

Промпт для моделей должен быть примерно таким:

Ты - профессиональный иллюстратор детских книг. Напиши подробное описание для изображения на основе следующей сцены из книги.

Сцена: {текст сцены}

Опиши изображение в деталях:
1. Персонажи: кто на изображении, их внешность, эмоции, позы
2. Обстановка: где происходит действие, фон, детали интерьера или природы
3. Стиль: художественный стиль (например, акварель, цифровая живопись, мультяшный)
4. Цветовая гамма: преобладающие цвета, настроение через цвет
5. Композиция: как расположены элементы на изображении

Описание должно быть достаточно детальным, чтобы по нему можно было нарисовать точную иллюстрацию.

Запускаем это через Ollama для обеих моделей. Если не знаешь, как настроить Ollama локально, посмотри мое полное руководство по локальному запуску Llama 3.1.

Код для генерации промптов:

import subprocess
import json

def generate_prompt_with_ollama(model, scene_text):
    prompt = f"""Ты - профессиональный иллюстратор детских книг. Напиши подробное описание для изображения на основе следующей сцены из книги.

Сцена: {scene_text}

Опиши изображение в деталях:
1. Персонажи: кто на изображении, их внешность, эмоции, позы
2. Обстановка: где происходит действие, фон, детали интерьера или природы
3. Стиль: художественный стиль (например, акварель, цифровая живопись, мультяшный)
4. Цветовая гамма: преобладающие цвета, настроение через цвет
5. Композиция: как расположены элементы на изображении

Описание должно быть достаточно детальным, чтобы по нему можно было нарисовать точную иллюстрацию."""
    
    cmd = ['ollama', 'run', model, prompt]
    result = subprocess.run(cmd, capture_output=True, text=True, encoding='utf-8')
    return result.stdout

# Генерация промптов для всех сцен
llama_prompts = []
mistral_prompts = []

for scene in scenes:
    llama_prompt = generate_prompt_with_ollama('llama3.1', scene)
    mistral_prompt = generate_prompt_with_ollama('mistral', scene)
    
    llama_prompts.append(llama_prompt)
    mistral_prompts.append(mistral_prompt)
    
    # Можно добавить задержку, чтобы не перегружать GPU
    import time
    time.sleep(1)

Теперь у нас есть два набора промптов. Следующий шаг - выбрать лучшие или скомбинировать их. Я обычно беру промпт от Mistral для детализации обстановки, а от Llama - для описания персонажей.

3 Шаг третий: генерируем изображения

Теперь самое интересное - превращаем текстовые описания в картинки. Я использую Qwen-Image-2512, потому что он дает качество, близкое к Midjourney, и при этом open-source.

Если у тебя мало VRAM, можешь попробовать Qwen-Image-Layered - он генерирует изображения по слоям, что иногда удобно для последующего редактирования. Или GLM-Image - гибрид, который и генерирует, и правит.

Для запуска Qwen-Image-2512 нужен Python с установленной библиотекой transformers. Вот пример кода:

from transformers import AutoModelForCausalLM, AutoTokenizer
from PIL import Image
import torch

model_id = "Qwen/Qwen-Image-2512"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
    model_id,
    torch_dtype=torch.float16,
    device_map="auto"
)

def generate_image(prompt, save_path="output.png"):
    # Формируем сообщение с промптом
    messages = [
        {
            "role": "user",
            "content": [
                {"type": "image", "image": "https://example.com/image.jpg"},  # Можно передать reference image, но у нас нет
                {"type": "text", "text": prompt}
            ]
        }
    ]
    
    # Тут нужно адаптировать под конкретный API Qwen-Image
    # Этот код упрощен, реальный вызов может отличаться
    text = tokenizer.apply_chat_template(
        messages,
        tokenize=False,
        add_generation_prompt=True
    )
    
    # Генерация
    # В реальности Qwen-Image требует специфичного вызова
    # Смотри документацию на Hugging Face
    
    print("Внимание: этот код упрощен. Реальная реализация зависит от API модели.")
    
    # Для примера, вот как работает Stable Diffusion:
    from diffusers import StableDiffusionPipeline
    pipe = StableDiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5")
    image = pipe(prompt).images[0]
    image.save(save_path)
    return save_path

# Генерация для каждого промпта
image_paths = []
for i, prompt in enumerate(combined_prompts):
    path = f"scene_{i}.png"
    generate_image(prompt, path)
    image_paths.append(path)
    print(f"Сгенерировано изображение {i+1}/{len(combined_prompts)}")

Важно: Qwen-Image-2512 требует много VRAM. На моей RTX 4090 с 24 ГБ он работает, но если у тебя карта слабее, придется использовать меньшие версии или уменьшать разрешение.

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

4 Шаг четвертый: проверяем, что картинка соответствует тексту

Вот тут многие обламываются. Сгенерировали кучу картинок, а они не соответствуют сцене. Персонажи не те, обстановка другая, вообще не понятно что.

Чтобы отсеять такой брак, используем Qwen3-VL - визуально-языковую модель. Она может анализировать изображение и отвечать на вопросы о нем.

Настроить Qwen3-VL не всегда просто - он иногда галлюцинирует, как я писал в статье про его галлюцинации. Но для нашей задачи он подходит.

Смысл в том, чтобы задать модели вопрос: "Насколько это изображение соответствует следующему описанию сцены: {текст сцены}? Оцени по шкале от 1 до 10, где 1 - совсем не соответствует, 10 - полностью соответствует."

Код для оценки:

from transformers import AutoModelForCausalLM, AutoTokenizer
from PIL import Image
import torch

# Загружаем Qwen3-VL
model_id = "Qwen/Qwen3-VL-7B"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
    model_id,
    torch_dtype=torch.float16,
    device_map="auto"
)

def evaluate_image(scene_text, image_path):
    # Открываем изображение
    image = Image.open(image_path)
    
    # Формируем промпт
    prompt = f"Насколько это изображение соответствует следующему описанию сцены? Оцени по шкале от 1 до 10, где 1 - совсем не соответствует, 10 - полностью соответствует.\n\nОписание сцены: {scene_text}\n\nОценка:"
    
    # Подготовка ввода для Qwen3-VL
    # Конкретный формат зависит от модели
    messages = [
        {
            "role": "user",
            "content": [
                {"type": "image", "image": image},
                {"type": "text", "text": prompt}
            ]
        }
    ]
    
    # Тут должен быть код для вызова модели
    # Упрощенно:
    inputs = tokenizer.apply_chat_template(messages, return_tensors="pt").to(model.device)
    
    with torch.no_grad():
        outputs = model.generate(inputs, max_new_tokens=10)
    
    response = tokenizer.decode(outputs[0], skip_special_tokens=True)
    
    # Парсим оценку из ответа
    # Модель может ответить "Оценка: 7" или просто "7"
    try:
        # Простой парсинг - ищем число в ответе
        import re
        numbers = re.findall(r'\d+', response)
        if numbers:
            score = int(numbers[-1])  # Берем последнее число
            if 1 <= score <= 10:
                return score
    except:
        pass
    
    return 0  # Если не удалось распарсить

# Оцениваем все изображения
scores = []
for i, (scene, image_path) in enumerate(zip(scenes, image_paths)):
    score = evaluate_image(scene, image_path)
    scores.append(score)
    print(f"Сцена {i+1}: оценка {score}/10")
    
    # Если оценка низкая, удаляем изображение или помечаем для перегенерации
    if score < 6:
        print(f"  Внимание: изображение не соответствует сцене!")

Теперь у нас есть оценка для каждой картинки. Все, что ниже 6 баллов, я отправляю на перегенерацию с уточненным промптом.

💡
Не доверяй оценке Qwen3-VL слепо. Иногда он ставит высокие баллы совершенно нерелевантным изображениям. Всегда выборочно проверяй результаты глазами.

5 Шаг пятый: финальный отбор и постобработка

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

  • Сгенерировать еще раз с тем же промптом (иногда получается лучше просто из-за случайности)
  • Переписать промпт, сделать его более детальным
  • Использовать другую модель генерации изображений

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

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

Наконец, сохраняем изображения в нужном формате и разрешении для книги. Обычно это PNG с прозрачным фоном или JPEG высокого качества.

Где этот пайплайн ломается и как это чинить

Идеальных систем не бывает. Вот самые частые проблемы, с которыми я сталкивался:

Проблема Причина Решение
Изображения не соответствуют тексту Промпты слишком общие, модель не понимает контекст Добавляй в промпт конкретные детали: имена персонажей, цвета одежды, время суток
Одинаковые изображения для разных сцен Модель застряла в одном шаблоне Используй разные сиды (seed) для генерации, добавляй вариации в промпты
Qwen3-VL ставит высокие оценки плохим изображениям Модель галлюцинирует или не понимает критерии Добавь человеческую проверку, используй несколько VLM для оценки
Процесс занимает слишком много времени Много сцен, тяжелые модели Уменьшай количество иллюстраций, используй более легкие модели, генерируй в несколько потоков

А если нужно не для книг?

Этот пайплайн можно адаптировать для других задач:

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

Фактически, это универсальный конвейер для превращения текста в изображения с проверкой качества. Главное - правильно настроить промпты и не ждать от моделей чудес.

Помни: ИИ-модели - это инструменты, а не волшебники. Они не понимают смысл текста, а лишь угадывают статистические закономерности. Поэтому результат всегда нужно проверять. Особенно если книга детская - там каждая картинка должна быть безопасной и соответствующей возрасту.

Что в итоге

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

Самые важные моменты:

  1. Не пытайся автоматизировать все. Выбирай только ключевые сцены.
  2. Инвестируй время в создание хороших промптов. Плохой промпт = плохое изображение.
  3. Всегда проверяй результаты. ИИ еще часто ошибается.
  4. Начинай с малого. Протестируй пайплайн на одной главе, а потом масштабируй.

Если ты хочешь глубже разобраться в работе с документами и ИИ, посмотри мои статьи про OLMocr 2 для чтения документов или про создание синтетических данных для обучения LLM. Там много смежных техник.

А если захочешь пойти еще дальше - можно добавить в пайплайн генерацию 3D-моделей, как в статье про Llama 3.1 и 3D-мебель. Но это уже совсем другая история.

Удачи в автоматизации! И помни: главное - не переставать думать своей головой, даже когда кажется, что ИИ все может сделать за тебя.