Iximy

На Пикабу
Дата рождения: 11 ноября
8023 рейтинг 7 подписчиков 0 подписок 31 пост 12 в горячем
Награды:
За заезд из Сочи
5

Где данные: RAG системы - как сделать болтливую нейросеть немного умнее

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

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

Многие встречались с такой ситуацией, когда нейросеть сначала начинает увлечено фантазировать, а когда ее ловят на несоответствиях переобувается в полете. Примерами таких галлюцинаций ИИ наверное может поделиться каждый, иногда не спасает ни режим размышления, ни поиск в сети. Когда выдача AI должна быть основана исключительно на проверенных данных используют RAG системы.

RAG это буквально - "Генерация, дополненная поиском". Именно такие системы позволяют AI дать пользователю ответ на вопрос, даже если у него нет достаточных данных для ответа, они подгрузятся благодаря RAG системе

Итак для чего нужны RAG системы

В первую очередь для того чтобы дополнить запрос к AI актуальными данными-контекстом, сначала ищем информацию в своей базе знаний, а после дополняем тем что нашли первоначальный запрос к AI. Как результат ChatGPT не фантазирует о средней температуре по больнице, а руководствуется исключительно вашими данными.

Представим пользователь решил уточнить у ChatGPT , какой смартфон купить, или куда съездить в отпуск, как итог вы получите массу полезной и не очень информации по интересующему вопросу, чему-то AI был обучен на этапе обучения, что то AI нашел в интернете. На этих обобщенных данных и будет построен ответ. А если нужна конкретика, основанная только на фактах, например наличии и ценах товаров, горячих путевках и т.д., то есть актуальных данных без которых не возможно дать полноценный ответ, здесь AI становится бесполезен, у него просто нет тех данных на базе которых вы хотите получить ответ.

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

Первое преимущество RAG - Приоритет данных

Вы и только вы определяете чем будет руководствоваться AI отвечая на запрос. Если вы укажете это в запросе модель не будет использовать свои знания при составлении ответа, даже если они говорят обратное. Такая генерация часто сопровождается оговоркой: "в рамках данного контекста", "согласно документам" — чтобы не вводить в заблуждение.

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

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

Второе преимущество - Управление данными

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

Огромное количество документов с чувствительными данными, например в медицинской или финансовой сфере, вы храните у себя, предоставляя только те данные которые требуются для запроса. Сам процесс подготовки данных многих пугает, однако как показывает практика современный документооборот и делопроизводство завязанные на CRM позволяют выгружать необходимые выборки в пару кликов. А прикрутив данные из 1С или баз данных можно формировать запросы в реальном времени, дополняя актуальными данными базу знаний RAG

Третье преимущество - Цена вопроса

Цена обработки RAG контекста ниже. Пока стоимость запроса считают по количеству токенов RAG будет более выгоден, чем передача несортированных данных по концепции "большого контекстного окна", хотя AI уже предлагают хранение данных без повторной загрузки

Представим что ваш запрос требует использования исключительно большой советской энциклопедии как источника, вы конечно можете передать БСЭ как контекст но AI посчитает эти данные как входящие токены, и соответственно тарифицирует. RAG система извлечет из энциклопедии небольшие фрагменты, в которых упоминается данные по вашему запросу и передаст AI только их, это позволяет экономить буквально в сотни, а то и в тысячи раз, в зависимости от объёма контента. А современные Hybrid RAG архитектуры позволяют извлекать контекст извлечённый несколькими механиками поиска и заведомо превышающий необходимый для ответа объём, предлагая AI самостоятельно выбрать наиболее релевантные фрагменты

Недостатки:

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

Есть вопросы пишите мне в ТГ подробнее про RAG на Habr

Показать полностью 3
7

Собираю мнения о проекте

Тепловая карта активности

Тепловая карта активности

Недавно я делился на пикабу своим проектом - онлайн сервисом для сбора метрик локации. Кратко: Указав любую точку на карте или введя адрес можно получить данные метрик района в радиусе 500м. Увидеть тепловую карту, смоделированный трафик, информацию о недвижимости, о жителях, инфраструктуре, присутствии и часах активности бизнеса.

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

Проект для получения базового набора данных останется бесплатным, без регистраций и подписок!

Показать полностью
0

Удалили пост

@moderator, , сообщение: "К сожалению, Ваш пост «Аналитика района за 30 секунд» удален с Пикабу. Причина: нарушение правил размещения ссылок" Какая часть правил нарушена, уточните пожалуйста? Бот по ссылке мой тег Мое

Удалили пост
Показать полностью 1
2

Аналитика района за 30 секунд

Поделюсь интересным AI сервисом, который по адресу выдает полезные данные об окружении недвижимости, в данный момент бесплатно:

Тепловая карта построена AI на базе данных POI точек и обученной модели весов

Тепловая карта построена AI на базе данных POI точек и обученной модели весов

  • Тепловую карту активности

  • Моделирование трафика

  • Графики активности

  • Сведения о недвижимости

  • Информацию о жителях

  • Данные об инфраструктуре

  • Часы активности бизнеса

  • Точки интереса - POI

  • Присутствие брендов

    Ничего сверхъестественного, просто удобный способ узнать, что вокруг выбранной точки. Может, кому пригодится.

Показать полностью
3

PDF ассистент: Учим робота читать. Часть 2

Пост "PDF ассистент: Учим робота читать. Часть 2." продолжает цикл постов о решении повседневных задач с помощью локальных нейросетей. В прошлом посте я рассказывал о создании PDF ассистента, для локальной обработки документов. Ранее был создан ИИ ассистент работающий полностью локально без доступа к сети интернет, которому можно "скормить" документ в формате PDF и на основе данных содержащихся в нем, отправить запрос нейросети. Однако в качестве исходных данных функционал позволял загрузить только документы в формате PDF, что лишало возможности обрабатывать сканы и фото документов.

В этой части проекта добавим загрузку сканов и фото документов в форматах .png,.jpg,.jpeg с автоматическим OCR распознаванием содержимого. Весь код доступен на странице проекта github

О проекте :

Зачастую чтобы найти нужную информацию в документе на несколько десятков страниц, необходимо потратить значительное время на ознакомление, если для текста есть поиск, то для более сложных задач требуются помощь нейросетей. Существует большое количество ИИ сервисов, которым можно "скормить" наши документы. К сожалению с учетом количества "сливов утечек" данных, загружать документы содержащих личные данные или конфиденциальные сведения плохая идея. Если использование в личных целях таких сервисов происходит на свой страх и риск, то применение в корпоративных целях зачастую недопустимо. Например вряд ли клиенты клиники будут рады если их медкарта окажется на серверах OpenAi.

Поскольку я специализируюсь на дообучении и интеграции локальных ИИ моделей в корпоративных задачах, решение этой задачи будет строится на применении исключительно локальных AI технологий. В основе проекта относительно недавно вышедшие на приемлемое качество хоть и урезанные по количеству параметров версии ИИ моделей, которые можно запустить даже на домашних ПК оснащенных видеокартами с объемом памяти от 6-8Гб. Для полноценных моделей по количеству параметров этого объема VRAM домашнего ПК конечно не достаточно, да и скорость работы домашних GPU не сравнится с коммерческими AI сервисами, но для обработки средних по объему документов вполне достаточно.

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

Реализация

Поскольку в проекте уже присутствует пользовательский web интерфейc, а также основные функции API, RAG и т.д. ограничимся минимальными изменениями.

Во первых добавим в web форму изменения буквально пары строк Расширим допустимые типы загружаемых файлов

<input type="file" id="file" name="file" accept=".pdf,.png,.jpg,.jpeg" style="display: none;">

Изменим текст кнопки загрузки

<button type="button" id="uploadButton">Загрузить файл (PDF/изображение)</button>

Для OCR функционала будем использовать библиотеку easyocr она доступна по лицензии Apache-2.0, могут потребоваться дополнительные зависимости , устанавливаем библиотеку:

pip install easyocr

Данные из загруженного и преобразованного в текст документа, обрабатываются в скрипте API сервера

Строки

context = extract_text_from_pdf(file_path)

response = generate_response(query, context, role) # Passing the role to the function

return jsonify({"response": response}), 200

Заменяем на

if file_path.endswith('.pdf'):

context = extract_text_from_pdf(file_path)

elif file_path.lower().endswith(('.png', '.jpg', '.jpeg')):

context = extract_text_from_image(file_path)

else:

return jsonify({"error": "Unsupported file type"}), 400

Добавляем функцию извлечения текста в document_prcessor.py

Подключаем библиотеку

import easyocr

def extract_text_from_image(file_path):

if not os.path.exists(file_path):

raise FileNotFoundError(f"File not found: {file_path}")

Устанавливаем поддержку русского и английского языков

reader = easyocr.Reader(['ru', 'en'])

result = reader.readtext(file_path)

Извлекаем текст из результата

text = ' '.join([detection[1] for detection in result])

return text

Проверим новый функционал

Загрузим скан сметы на строительство дома в PNG формате 1240х1754

Как видно из генерации ответа, библиотека успешно справилась с распознаванием

Попробуем загрузить изображение с сканом расчета зарплаты:

Зарплатный лист

Зарплатный лист

Также успешный результат обработки изображения

Этот мини проект всего лишь один из примеров использования AI технологий, для повседневных задач

Цель проекта достигнута. а значит еще один рабочий проект отправляется в копилку мини проектов "выходного дня"

С учетом того что здесь затруднительно публиковать читаемый код корректно с TABами, весь код доступен на странице проекта github

Вопросы по коду можете писать мне в ТГ

Показать полностью 2
3

PDF ассистент: Создаем локального ИИ помощника. Часть 1

PDF ассистент: Создаем локального ИИ помощника. Часть 1

Пост "Создаем локального ИИ помощника. Часть 1." продолжает цикл постов о решении повседневных задач с помощью локальных нейросетей. В прошлом посте я рассказывал о создании локальной ИИ системы поиска по изображениям

Зачастую чтобы найти нужную информацию в документе на несколько десятков страниц, необходимо потратить значительное время на ознакомление, если для текста есть поиск, то для более сложных задач требуются помощь нейросетей. Существует большое количество ИИ сервисов, которым можно "скормить" наши документы. К сожалению с учетом количества "сливов утечек" данных, загружать документы содержащих личные данные или конфиденциальные сведения плохая идея. Если использование в личных целях таких сервисов происходит на свой страх и риск, то применение в корпоративных целях зачастую недопустимо. Например вряд ли клиенты клиники будут рады если их медкарта окажется на серверах OpenAi.

Поскольку я специализируюсь на дообучении и интеграции локальных ИИ моделей в корпоративных задачах, решение этой задачи будет строится на применении исключительно локальных AI технологий. В основе проекта относительно недавно вышедшие на приемлемое качество хоть и урезанные по количеству параметров версии ИИ моделей, которые можно запустить даже на домашних ПК оснащенных видеокартами с объемом памяти от 6-8Гб. Для полноценных моделей по количеству параметров этого объема VRAM домашнего ПК конечно не достаточно, да и скорость работы домашних GPU не сравнится с коммерческими AI сервисами, но для обработки средних по объему документов вполне достаточно.

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

Примеры использования

Как это выглядит на практике. Загружаем документ например "Закон о защите прав потребителей" или "Ипотечный договор" и отправляем запрос:

Здесь слева загружаем документ и справа задаем вопрос в данных примерах загружен ЗоЗПП и договор ипотеки.

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

Тот же подход применим и для корпоративных задач.

В этих трех примерах проверяем смету на строительство, подбираем код из справочника ОКВЭД, и вытаскиваем из стратегии развития нужную информацию

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

Загруженные виды документов Datasheet ATMEGA328, User manual экшн камеры, Service manual от микроволновки и сплит системы

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

Интересный пример анализа оценок с выдачей рекомендаций из табеля успеваемости:

В качестве документа "скормили" табель успеваемости ученика 7 класса

Скорость: На локальных ресурсах время на генерацию ответа зависит от производительности GPU. В приведённых примерах составляло в пределах 15-25 сек\запрос, что как показывает практика, при выводе в потоковом режиме, практически гарантировано обеспечивают скорость генерации сравнимую с скоростью чтения.

Реализация

Для реализации нам понадобится:

  1. Установить следующие зависимости Python, ollama, git и Библиотеки os, Json, ollama,Flask, loging, os, pyPDF2

  2. Клонировать или скачать GIT репозиторий командой git clone https://github.com/iximy/AI-PDF-assistant.git

  3. Настроить файл конфигурации config/config.json

  4. Скачать и запустить нашу модель командой из quick_start, понадобится около 10 Гб свободного пространства

  5. Запустить сервер командой python main.py

  6. Открыть web интерфейс в браузере по адресу http://localhost:5000

Для преобразования PDF будем использовать бесплатную и открытую библиотеку PyPDF2

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

API сервер обеспечивает реализацию работы API, обрабатывает входящие запросы от формы веб интерфейса,

Веб интерфейс реализует минималистичный интерфейс загрузки документов, выбора роли ассистента, поле ввода сообщений пользователя и окно чата

RAG модуль (урезанная версия). Обеспечивает создание запроса к ИИ модели на основе контекста из документов хранящихся в БД. Подробнее о RAG системах можете почитать в моей статье

Document processor (Обработчик документов) Обеспечивает обработку загруженных документов для дальнейшей обработки

Logger - для сохранения истории запросов к API, значительно облегчает отладку

API сервер

Построен на библиотеке Flask, обеспечивает обработку запросов от WEB формы или внешних приложений.

Загружаем используемые библиотеки

from flask_cors import CORS

from flask import Flask, request, jsonify, render_template

from utils.document_processor import extract_text_from_pdf, save_document

from utils.rag import generate_response

import os

import json

Запускаем сервер

app = Flask(__name__, template_folder='../web/templates', static_folder='../web/static')

Маршрут для корневой страницы

@app.route('/upload', methods=['POST'])

def upload_document():

if 'file' not in request.files:

return jsonify({"error": "No file part"}), 400

file = request.files['file']

if file.filename == '':

return jsonify({"error": "No selected file"}), 400

file_path = save_document(file, file.filename)

return jsonify({"message": "File uploaded successfully", "file_path": file_path}), 200

Маршрут для запроса к модели

@app.route('/ask', methods=['POST'])

def ask_question():

data = request.json

if not data:

return jsonify({"error": "No data provided"}), 400

# Blocking incoming data

print("Incoming data:", data)

query = data.get('query')

file_path = data.get('file_path')

role = data.get('role', 'assistant') # The default role is "Assistant"

if not query or not file_path:

return jsonify({"error": "Missing query or file_path"}), 400

try:

context = extract_text_from_pdf(file_path)

response = generate_response(query, context, role) # Passing the role to the function

return jsonify({"response": response}), 200

except Exception as e:

# Logging the error

print("Error in ask_question:", str(e))

return jsonify({"error": "Internal server error"}), 500

Базовый URL

Все запросы API выполняются к базовому URL:

http://localhost:5000

Эндпоинты API

1. Загрузка PDF документа

Запрос

  • Метод: POST

  • URL: /upload

  • Тип содержимого: multipart/form-data

  • Параметры: file (обязательный): PDF файл для загрузки.

Пример запроса

curl -X POST -F "file=@document.pdf" http://localhost:5000/upload

Успешный ответ:

{

"message": "File uploaded successfully",

"file_path": "documents/document.pdf"

}

Ошибка:

{

"error": "No file part"

}

2. Задать вопрос на основе загруженного документа

Запрос

  • Метод: POST

  • URL: /ask

  • Тип содержимого: application/json

  • Параметры:

    - query (обязательный): Вопрос, на который нужно ответить.

    - file_path (обязательный): Путь к загруженному PDF файлу.

    - role (опциональный): Роль помощника (по умолчанию assistant).

Пример запроса

curl -X POST -H "Content-Type: application/json" -d '{

"query": "What is the main topic?",

"file_path": "documents/document.pdf",

"role": "expert"

}' http://localhost:5000/ask

Ответ

Успешный ответ:

{

"response": "The main topic is artificial intelligence."

}

Ошибка:

{

"error": "Missing query or file_path"

}

Пример использования

Загрузите PDF документ:

curl -X POST -F "file=@document.pdf" http://localhost:5000/upload

Ответ:

{

"message": "File uploaded successfully",

"file_path": "documents/document.pdf"

}

Задайте вопрос на основе загруженного документа:

curl -X POST -H "Content-Type: application/json" -d '{

"query": "Какая тема документа?",

"file_path": "documents/document.pdf",

"role": "expert"

}' http://localhost:5000/ask

Ответ:

{

"response": "Документ описывает планы развития компании на 2025 год."

}

Обработка ошибок

API возвращает следующие коды состояния HTTP:

  • 200 OK: Запрос выполнен успешно.

  • 400 Bad Request: Неверный запрос (например, отсутствует обязательный параметр).

  • 500 Internal Server Error: Внутренняя ошибка сервера.

Логирование

Все запросы и ошибки логируются в файл logs/app.log. Уровень логирования можно настроить в конфигурационном файле config/config.json.

Подключаем библиотеки

import logging

import json

import os

Загружаем конфигурацию

with open('config/config.json') as config_file:

config = json.load(config_file)

Создаем запись лога

logging.basicConfig(

level=config['logging']['level'],

format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',

filename=config['logging']['file']

)

logger = logging.getLogger(__name__)

Конфигурация

Настройки API, такие как хост, порт, путь к документам и ключ API для Ollama, хранятся в файле config/config.json. Пример конфигурации:

{

"ollama": {

"model_name": "model_name",

"host": "http://localhost:11434"

},

"server": {

"host": "0.0.0.0",

"port": 5000

},

"logging": {

"level": "INFO",

"file": "logs/app.log"

},

"documents_path": "documents/"

}

Веб-интерфейс

Веб-интерфейс доступен по адресу http://localhost:5000. Он позволяет:

  • Загружать PDF документы.

  • Выбирать роль помощника (например, "Ассистент", "Эксперт", "Переводчик")-опционально

  • Задавать вопросы и получать ответы отображая их в формате чата.

RAG модуль

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

from ollama import Client

import json

Загружаем конфигурацию

with open('config/config.json') as config_file:

config = json.load(config_file)

Инициализация клиента Ollama

client = Client(host=config['ollama']['host'])

Формируем сообщение с контекстом и запросом

messages = [

{"role": "system", "content": f"You are a {role}. Provide helpful and accurate answers."},

{"role": "user", "content": f"Context: {context}\n\nQuery: {query}"}

]

Отправляем запрос к модели

response = client.chat(

model=config['ollama']['model_name'],

messages=messages

)

Возвращаем ответ

return response['message']['content']

Document processor

Обработчик документов построен на библиотеке PyPDF2 и обеспечивает обработку загруженных документов для дальнейшей обработки место сохранения загруженных документов определено в параметре "documents_path" файла конфигурации config.json

import PyPDF2

import os

import json

Загружаем конфигурацию

with open('config/config.json') as config_file:

config = json.load(config_file)

Извлекаем текст

def extract_text_from_pdf(file_path):

with open(file_path, 'rb') as file:

reader = PyPDF2.PdfReader(file)

text = ''

for page in reader.pages:

text += page.extract_text()

return text

Сохраняем документ

def save_document(file, filename):

documents_path = config['documents_path']

if not os.path.exists(documents_path):

os.makedirs(documents_path)

file_path = os.path.join(documents_path, filename)

with open(file_path, 'wb') as f:

f.write(file.read())

return file_path

Этот мини проект всего лишь один из примеров использования AI технологий, для повседневных задач

Цель проекта достигнута. а значит еще один рабочий проект отправляется в копилку мини проектов "выходного дня"

С учетом того что здесь затруднительно публиковать читаемый код корректно с TABами, весь код доступен на странице проекта github

Вопросы по коду можете писать мне в ТГ

Показать полностью 12
10

Свои гугл картинки на минималках. AI автотегер-индексатор изображений: как навести порядок в хаосе фотоальбомов

Вспомните когда последний раз пытались найти нужное фото с ДР ребенка, или тот самый скриншот среди тысяч файлов, в разных папках на компьютере или телефоне. Я столкнулся с этой проблемой и начал искать решения. В сети куча ИИ сервисов в которые можно загрузить свои фото а в ответ получить легкий поиск по ним, по запросам вроде: лето лес, отдых на море или чек из магазина, однако желающих сливать весь свой семейный фотоархив на чужие платформы, с неизвестными перспективами их использования не так много. Поскольку я специализируюсь на дообучении и интеграции ИИ моделей, решение этой задачи будет строится на применении AI технологий.

Еще пару лет назад для генерации текста а тем более обработки изображений требовались довольно серьезные аппаратные ресурсы, относительно недавно появились доступные, хоть и урезанные по количеству параметров vision версии ИИ моделей, которые можно запустить даже на домашних ПК оснащенных видеокартами с объемом памяти от 8Гб. Для полноценных моделей этого обьема VRAM домашнего ПК конечно не достаточно, да и скорость работы с 8Гб не сравнится с коммерческими версиями, но в условиях нашей задачи, время на обработку и индексацию не ограничено, и если последовательно "скормить" локальной ИИ модели все наши фото, получив взамен их описание, которое будет сохранено в базу данных, а после прикрутить поиск по БД, то мы сможем получить полноценный текстовый поиск по фото, а самое главное локальный, без выгрузки наших фото в сеть

Как это работает на практике?

1. Закидываете все изображения в папку images и запускаете скрипт индексации

2. ИИ сам их описывает, тегирует и делает доступными для поиска.

3. Чтобы найти фото например дня рождения ребенка с тортом, пишите в поиске День рождения, торт

Из плюсов:

- Работает локально!!! – никакого риска утечки данных, т.к. фото не выгружаются в сеть

- Не требует подписки оплаты и покупки софта

- Можно искать фото не только по тегам, но и по смыслу

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

Итак приступаем:

Устанавливаем зависимости: ПО Python, ollama и Библиотеки os, Json, ollama, chromadb, PIL Flask

Скачиваем и запускаем нашу модель командой ollama run llama3.2-vision:11b понадобится около 10 Гб свободного пространства

Теперь непосредственно к скрипту

Создаем файл скрипта отвечающий за распознавание и индекс фото. Подключаем библиотеки

import os

import json

import ollama

import chromadb

from chromadb.utils import embedding_functions

from PIL import Image

from ollama import Client

Указываем расположение каталогов с фото и БД

IMAGE_FOLDER = "./images" # Папка с нашими фото

DB_FOLDER = "./chroma_db" # Папка для хранения базы ChromaDB

Инициализируем ChromaDB

chroma_client = chromadb.PersistentClient(path=DB_FOLDER)

collection = chroma_client.get_or_create_collection(

name="image_tags",

metadata={"hnsw:space": "cosine"},

embedding_function=embedding_functions.DefaultEmbeddingFunction()

)

Указываем параметры одкючения к API Ollama

client = Client(

host='http://localhost:11434',

headers={'x-some-header': 'some-value'}

)

Генерируем текстовое описание наших фото, промпт отправляемый для генерации описания можно отредактировать под потребности

def generate_tags(image_path):

response = client.chat(

model="llama3.2-vision:11b", # Здесь указываем нашу модель ИИ

messages=[

{"role": "user", "content": "Что на этом изображении? Ответ в 20слов", "images": [image_path]}

]

)

return response["message"]["content"].strip()

Перебираем все изображения в папке вызываем генерацию и сохраняем их текстовое описание в ChromaDB

def index_images():

for filename in os.listdir(IMAGE_FOLDER):

if filename.lower().endswith((".jpg", ".png", ".jpeg")):

image_path = os.path.join(IMAGE_FOLDER, filename)

tags = generate_tags(image_path)

collection.add(

ids=[filename],

documents=[tags],

metadatas=[{"filename": filename}]

)

print(f" {filename}: {tags}")

Запускаем индексацию наших фоточек

if __name__ == "__main__":

index_images()

Сохраняем как ai-indexer.py

Второй скрипт отвечает за поисковый алгоритм и серверную часть:

Подключаем библиотеки

from flask import Flask, render_template, request

import chromadb

Указываем путь где находится наша база данных

DB_FOLDER = "./chroma_db"

Указываем порог отсечки для семантического поиска, где 1 более строгий поиск

SCORE_THRESHOLD = 0.5

Подключаемся к ChromaDB

chroma_client = chromadb.PersistentClient(path=DB_FOLDER)

collection = chroma_client.get_or_create_collection("image_tags")

Инициализируем Flask, не забыв указать папку наших изображений для выдачи,

app = Flask(__name__, static_folder='images')

Последовательный поиск: сначала точное совпадение, затем семантический поиск по установленному ранее порогу

def search_images(query):

results = collection.query(query_texts=[query], n_results=10)# Ограничим количество фото в выдаче

if not results["ids"]:

return []

exact_matches = []

semantic_matches = []

for i, description in enumerate(results["documents"][0]):

filename = results["metadatas"][0][i]["filename"]

score = results["distances"][0][i]

Проверка на точное совпадение

if query.lower() in description.lower():

exact_matches.append(filename)

Добавляем совпадения семантического поиска согласно установленого ранее порога

elif score <= SCORE_THRESHOLD:

semantic_matches.append((filename, score))

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

semantic_matches.sort(key=lambda x: x[1])

Возвращаем точные, затем семантические совпадения

return exact_matches + [x[0] for x in semantic_matches]

Добавляем обработку серверной части для точки входа /, по запросу отдаем данные

@app.route("/", methods=["GET", "POST"])

def index():

if request.method == "POST":

query = request.form["query"].strip()

if query.lower() == "exit":

return render_template("index.html", images=[])

matches = search_images(query)

return render_template("index.html", images=matches)

return render_template("index.html", images=[])

if __name__ == "__main__":

app.run(debug=True)

сохраняем скрипт как search_server.py.

Создаем папку templates и помещаем туда файл веб интерфейса index.html

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Поиск изображений</title>

<style>

body { font-family: Arial, sans-serif; }

.container { width: 80%; margin: 0 auto; text-align: center; }

.images { display: flex; flex-wrap: wrap; justify-content: center; }

.image-container { margin: 10px; }

img { width: 200px; height: auto; border-radius: 10px; }

.form-container { margin-bottom: 20px; }

input[type="text"] { padding: 10px; width: 300px; font-size: 16px; }

input[type="submit"] { padding: 10px 20px; font-size: 16px; background-color: #4CAF50; color: white; border: none; cursor: pointer; }

input[type="submit"]:hover { background-color: #45a049; }

</style>

</head>

<body>

<div class="container">

<h1>Поиск изображений</h1>

<div class="form-container">

<form method="POST">

<input type="text" name="query" placeholder="Введите запрос для поиска..." required>

<input type="submit" value="Поиск">

</form>

</div>

<div class="images">

{% if images %}

{% for image in images %}

<div class="image-container">

<img src="{{ url_for('static', filename=image) }}" alt="{{ image }}">

</div>

{% endfor %}

{% else %}

<p>Не найдено изображений по вашему запросу.</p>

{% endif %}

</div>

</div>

</body>

</html>

Теперь создаем папку images и закидываем туда наши фото, рекомендую не закидывать оригиналы фото в полном разрешении, а сделать глобальный resize c сохранением имени до разрешения 250-300px по широкой стороне, с подобным разрешением обработка и индексация 1000 фото при скорости 30-40 сек\изображение. займет порядка 8-11 часов. Без сжатия индексация того же объема фото может занять до нескольких суток

Для поста, в обучающих целях я использовал простую подборку изображений из интернета

Тестовый набор изображений

Тестовый набор изображений

Запускаем скрипт в командной строке

В процессе индексации будет создан каталог chroma_db где разместится база данных, а в окне можно сразу видеть сгенерированные ИИ текстовые описания наших изображений

Процесс индексации и генерации описаний изображений ИИ

Процесс индексации и генерации описаний изображений ИИ

По завершении скрипта можно запускать поисковый сервер

В браузере вводим адрес: http://localhost:5000 и видим простейшую поисковую форму

Вводим о очереди тестовые запросы: комната, велосипед, дорожный знак, транспорт, кровать, диван

Как видим из этих 6 примеров поисковый алгоритм прекрасно справляется с выдачей изображений, поиск работает довольно быстро. При необходимости можно откорректировать значение SCORE_THRESHOLD, которое отвечает за порог точности при семантическом поиске.

Этот мини проект всего лишь один из примеров использования AI технологий, для повседневных задач

Цель проекта достигнута. а значит еще один рабочий проект отправляется в копилку мини проектов "выходного дня"

Здесь GIT проекта и мой ТГ

Показать полностью 9
Отличная работа, все прочитано!

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества