Реализация Multimodal AI обработка текста изображений аудио

Проектируем и внедряем системы искусственного интеллекта: от прототипа до production-ready решения. Наша команда объединяет экспертизу в машинном обучении, дата-инжиниринге и MLOps, чтобы AI работал не в лаборатории, а в реальном бизнесе.
Показано 1 из 1 услугВсе 1566 услуг
Реализация Multimodal AI обработка текста изображений аудио
Сложная
~1-2 недели
Часто задаваемые вопросы
Направления AI-разработки
Этапы разработки AI-решения
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1218
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    853
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1047
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    561
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    825

Реализация Multimodal AI: обработка текста, изображений и аудио

Мультимодальные системы объединяют несколько типов данных в единый pipeline. Реальные задачи: анализ медицинских снимков с голосовым вводом врача, обработка накладных (сканы + распознавание), мониторинг производства (видео + сенсорные данные). Ключевые компоненты: Vision LLM, Whisper/Speech-to-Text, Text-to-Speech, Document Understanding.

Архитектура мультимодального pipeline

from anthropic import AsyncAnthropic
from openai import AsyncOpenAI
import base64
import aiohttp
from pathlib import Path
from typing import Union
from pydantic import BaseModel

anthropic_client = AsyncAnthropic()
openai_client = AsyncOpenAI()

class MultimodalInput(BaseModel):
    text: str | None = None
    image_paths: list[str] = []
    audio_path: str | None = None
    document_path: str | None = None

class MultimodalPipeline:

    async def process(self, input_data: MultimodalInput, task: str) -> str:
        """Обрабатывает мультимодальный ввод"""
        content_blocks = []

        # 1. Аудио → текст
        if input_data.audio_path:
            transcript = await self.transcribe_audio(input_data.audio_path)
            content_blocks.append({"type": "text", "text": f"[Аудио транскрипция]: {transcript}"})

        # 2. Изображения
        for image_path in input_data.image_paths:
            image_block = await self.prepare_image(image_path)
            content_blocks.append(image_block)

        # 3. Документы (PDF)
        if input_data.document_path:
            doc_text = await self.extract_document(input_data.document_path)
            content_blocks.append({"type": "text", "text": f"[Документ]:\n{doc_text}"})

        # 4. Текстовый запрос
        if input_data.text:
            content_blocks.append({"type": "text", "text": input_data.text})

        content_blocks.append({"type": "text", "text": f"\nЗадача: {task}"})

        response = await anthropic_client.messages.create(
            model="claude-sonnet-4-5",
            max_tokens=4096,
            messages=[{"role": "user", "content": content_blocks}],
        )

        return response.content[0].text

    async def transcribe_audio(self, audio_path: str) -> str:
        """Транскрипция аудио через Whisper"""
        with open(audio_path, "rb") as f:
            transcription = await openai_client.audio.transcriptions.create(
                file=(Path(audio_path).name, f.read()),
                model="whisper-1",
                language="ru",
            )
        return transcription.text

    async def prepare_image(self, image_path: str) -> dict:
        """Подготавливает изображение для Claude Vision"""
        if image_path.startswith("http"):
            # URL изображения
            async with aiohttp.ClientSession() as session:
                async with session.get(image_path) as resp:
                    image_data = base64.b64encode(await resp.read()).decode()
            media_type = resp.content_type or "image/jpeg"
        else:
            # Локальный файл
            with open(image_path, "rb") as f:
                image_data = base64.b64encode(f.read()).decode()
            ext = Path(image_path).suffix.lower()
            media_type = {"jpg": "image/jpeg", "jpeg": "image/jpeg",
                         "png": "image/png", "gif": "image/gif",
                         "webp": "image/webp"}.get(ext[1:], "image/jpeg")

        return {
            "type": "image",
            "source": {"type": "base64", "media_type": media_type, "data": image_data}
        }

    async def extract_document(self, pdf_path: str) -> str:
        """Извлекает текст из PDF документа"""
        import pdfplumber

        text_parts = []
        with pdfplumber.open(pdf_path) as pdf:
            for page in pdf.pages:
                text = page.extract_text()
                if text:
                    text_parts.append(text)

        return "\n\n".join(text_parts)[:10000]

Практический кейс: система обработки накладных

class InvoiceProcessor:
    """Обрабатывает сканы накладных: изображение + извлечение данных"""

    def __init__(self):
        self.pipeline = MultimodalPipeline()

    async def process_invoice_scan(self, image_path: str) -> dict:
        """Извлекает данные из скана накладной"""

        input_data = MultimodalInput(
            image_paths=[image_path],
            text="Извлеки данные накладной"
        )

        response = await anthropic_client.messages.create(
            model="claude-sonnet-4-5",
            max_tokens=2048,
            messages=[{
                "role": "user",
                "content": [
                    await self.pipeline.prepare_image(image_path),
                    {
                        "type": "text",
                        "text": """Извлеки данные из накладной. Верни JSON:
{
  "vendor": "поставщик",
  "invoice_number": "номер",
  "date": "дата",
  "items": [{"name": "...", "qty": 0, "price": 0}],
  "total": 0,
  "vat": 0,
  "currency": "RUB"
}"""
                    }
                ]
            }],
        )

        import json
        text = response.content[0].text
        return json.loads(text[text.find("{"):text.rfind("}") + 1])

Speech-to-Text + AI + Text-to-Speech pipeline

async def voice_assistant_pipeline(audio_input: bytes) -> bytes:
    """Голосовой ввод → AI ответ → голосовой вывод"""

    # 1. Speech-to-Text
    transcription = await openai_client.audio.transcriptions.create(
        file=("audio.webm", audio_input),
        model="whisper-1",
        language="ru",
    )
    user_text = transcription.text

    # 2. LLM обработка
    response = await anthropic_client.messages.create(
        model="claude-haiku-4-5",
        max_tokens=512,
        messages=[{"role": "user", "content": user_text}]
    )
    answer_text = response.content[0].text

    # 3. Text-to-Speech
    tts_response = await openai_client.audio.speech.create(
        model="tts-1",
        voice="alloy",
        input=answer_text,
        response_format="mp3",
    )

    return tts_response.content

Анализ видео через покадровую обработку

import cv2

async def analyze_video(video_path: str, task: str, sample_fps: int = 1) -> str:
    """Анализирует видео, семплируя кадры"""
    cap = cv2.VideoCapture(video_path)
    fps = cap.get(cv2.CAP_PROP_FPS)
    frame_interval = int(fps / sample_fps)

    frames = []
    frame_count = 0

    while cap.isOpened() and len(frames) < 10:  # Максимум 10 кадров
        ret, frame = cap.read()
        if not ret:
            break

        if frame_count % frame_interval == 0:
            _, buffer = cv2.imencode(".jpg", frame, [cv2.IMWRITE_JPEG_QUALITY, 60])
            frames.append(base64.b64encode(buffer).decode())

        frame_count += 1

    cap.release()

    content = [{"type": "text", "text": f"Проанализируй видео ({len(frames)} кадров):"}]
    for i, frame_data in enumerate(frames):
        content.append({
            "type": "image",
            "source": {"type": "base64", "media_type": "image/jpeg", "data": frame_data}
        })
    content.append({"type": "text", "text": task})

    response = await anthropic_client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=2048,
        messages=[{"role": "user", "content": content}],
    )
    return response.content[0].text

Практический кейс: контроль качества на производстве

Задача: завод по производству электроники, 100+ продуктов в час, ручной осмотр = 15% пропущенных дефектов.

Система:

  • Камера делает снимок каждого продукта
  • Claude Vision анализирует на наличие дефектов (царапины, неправильная пайка)
  • Звуковой сигнал при обнаружении дефекта
  • Статистика по типам дефектов за смену

Результаты:

  • Обнаружение дефектов: 15% пропуска → 3% пропуска
  • Скорость обработки: 2 сек/продукт (vs 30 сек ручной осмотр)
  • Экономия: -4 оператора ОТК на линии

Сроки

  • Vision анализ изображений: 2–3 дня
  • Whisper транскрипция: 1–2 дня
  • Голосовой pipeline (STT + TTS): 1 неделя
  • Видео анализ: 1–2 недели
  • Production-система с очередью: 2–3 недели