Предлагаем вашему вниманию проектную работу для курса «Архитектура и шаблоны проектирования«.
Введение
Добрый день!
Меня зовут Беляев-Козырев Григорий Николаевич и сегодня в данной статье мы рассмотрим процесс создания Телеграм-бота для генерации изображений на основе текстового запроса. Для реализации генерации используется Docker-контейнер с установленной stable diffusion-моделью. Этот бот позволяет пользователям выбирать модель и количество шагов для генерации изображения.
Технические детали
Telegram Bot и основные библиотеки
В коде используется библиотека python—telegram—bot для создания и управления Телеграм-ботом. Для отправки запросов на генерацию изображений используется библиотека requests. Дополнительно используются библиотеки для работы с изображениями (PIL) и перевода текста (googletrans).
Docker и Stable Diffusion
Генерация изображений происходит в контейнере Docker, который развернут локально. Внутри контейнера используется stable diffusion-модель для создания изображений на основе текстового запроса. Stable diffusion – это метод генерации изображений, который использует диффузионные процессы для создания высококачественных и разнообразных визуальных контентов.
API и система генерации
Бот взаимодействует с генеративной службой, предоставленной через API. Пользовательский запрос, содержащий текстовую подсказку и другие параметры, отправляется в виде JSON-запроса на сервер службы. Этот запрос включает в себя информацию о выбранной модели, количестве шагов и других настройках.
Пример:
json_data = {
"prompt": "beatiful dog",
"seed": 12123231,
"used_random_seed": True,
"negative_prompt": "",
"num_outputs": 1,
"num_inference_steps": 50,
"guidance_scale": 7.5,
"width": 512,
"height": 512,
"vram_usage_level": "high",
"sampler_name": "euler_a",
"use_stable_diffusion_model": sd-v1.5,
"clip_skip": False,
"use_vae_model": "",
"stream_progress_updates": True,
"stream_image_progress": False,
"show_only_filtered_image": True,
"block_nsfw": False,
"output_format": "jpeg",
"output_quality": 75,
"output_lossless": False,
"metadata_output_format": "none",
"original_prompt": "beatiful dog",
"active_tags": [],
"inactive_tags": [],
"use_face_correction": "GFPGANv1.4",
"use_upscale": "RealESRGAN_x4plus_anime_6B",
"upscale_amount": "4",
"session_id": 412551212412
}
Сервер обрабатывает запрос, инициирует процесс генерации в контейнере Docker и создаёт уникальный идентификатор задачи (task ID).
Затем каждую секунду бот по запросу http://localhost:9000/ping?session_id={telegram_chat_id} получает информацию о текущем состоянии запроса для пользователя с заданным telegram_chat_id.
Возможно три состояния системы – Busy, Online, Failed.
Состояние Online означает, что система окончила генерацию изображения и готова к его отправке.
Далее в запросе присутствуют запросы с информацией о задачах tasks, каждый из которых содержит task ID.
Eсли задача имеет статус buffer – то эта задача считается выполненной и изображение доступно по адресу http://localhost:9000/image/stream/{task_id} в формате base64.
Далее данное изображение следует передать пользователю по его уникальному telegram_chat_id.
Пример кода ежесекундной проверки от бота к системе и отправки изображения в случае успеха:
# Function to retrieve the generated image
def get_generated_image(task_id):
image_url = f"http://localhost:9000/image/stream/{task_id}"
response = requests.get(image_url)
if response.status_code == 200:
response_text = response.text
# Trim the string
search_str = '{"status":'
start_index = response_text.find(search_str)
if start_index != -1:
trimmed_string = response_text[start_index:]
else:
trimmed_string = response_text
# Parse the trimmed string as JSON
try:
response_data = json.loads(trimmed_string)
except json.JSONDecodeError as e:
print(f"Error parsing JSON: {e}")
return None
if response_data["status"] == "succeeded" and response_data.get("output"):
image_data = response_data["output"][0].get("data")
return image_data
return None
# Function to send the generated image to the user
def send_image_from_base64(bot, chat_id, base64_data):
try:
# Remove the "data:image/jpeg;base64," prefix if it exists
base64_data = base64_data.replace("data:image/jpeg;base64,", "")
# Decode base64 data
image_data = base64.b64decode(base64_data)
# Create an in-memory BytesIO buffer for the image
image_buffer = BytesIO(image_data)
# Open the image using PIL (Python Imaging Library)
image = Image.open(image_buffer)
# You can save the image to a file if needed:
image.save("output" + str(chat_id) + ".jpg")
# Send the image as a photo
bot.send_photo(chat_id, photo=open("output" + str(chat_id) + ".jpg", 'rb'))
except Exception as e:
print(f"Error sending image: {e}")
# Function to check the rendering status periodically
def check_rendering_status(chat_id, bot):
session_id = session_data[chat_id]["session_id"]
while True:
# Ping the service to get the rendering status
ping_url = f"http://localhost:9000/ping?session_id={session_id}"
response = requests.get(ping_url)
if response.status_code == 200:
response_data = response.json()
if response_data["status"] == "Online" and response_data.get("tasks"):
# Get all task IDs
task_ids = response_data["tasks"]
for task_id, status in task_ids.items():
# Get the generated image
if status == 'buffer':
generated_image = get_generated_image(task_id)
if generated_image:
send_image_from_base64(bot, chat_id, generated_image)
return # Rendering is complete, exit the loop
time.sleep(1) # Wait for 1 second before checking again
Опции Телеграм-бота
Выбор опций в боте реализован при помощи кнопки KeyboardButton из python-telegram-bot.
Выбор модели
Бот предоставляет пользователю возможность выбора модели из нескольких предустановленных вариантов. Модели включают в себя, например, «3dAnimationDiffusion_v10», «AnythingV5Ink_ink», «ghibliStyleMix_v10» и другие.
Количество шагов
Пользователь может задать количество шагов (inference steps), определяющих детализацию и сложность создаваемого изображения. Выбор значения влияет на время и ресурсы, затрачиваемые на генерацию.
Как это работает
- Старт беседы: Пользователь начинает беседу с ботом командой «/start». Сессия инициализируется, и устанавливаются параметры по умолчанию для модели и количества шагов.
- Выбор модели и количества шагов: Пользователь может выбирать модель и количество шагов из главного меню. Бот сохраняет эти параметры в сессии пользователя.
- Ввод текстовой подсказки: Пользователь вводит текстовую подсказку для генерации изображения. Текст переводится на английский язык для стабильной работы с моделью.
- Запрос на генерацию: Бот отправляет запрос с параметрами, включая текстовую подсказку, на сервер генерации. Запускается процесс генерации в Docker-контейнере.
- Проверка статуса: Запускается отдельный поток, который периодически проверяет статус генерации. Когда изображение готово, оно получается и отправляется пользователю в Телеграм.
Примеры работы бота
Заключение
Создание Телеграм-бота для генерации изображений на основе текстовых подсказок — это захватывающий процесс, который включает в себя использование технологий Docker, Stable diffusion и интеграции с Телеграм API. Полученный бот предоставляет пользователям удобный способ создания уникальных и креативных изображений.
Контакты для связи:
Tel. +7 921 893 5001
E-mail: [email protected]
Telegram: https://t.me/KGB_N
P. S. Интересуюет архитектура ПО и шаблоны проектирования? Добро пожаловать на специализированный курс в Otus!