AI-модерация изображений в мобильном приложении
Изображения модерировать сложнее текста. Пользователь пытается обойти фильтры: редактирует фото, меняет разрешение, добавляет наклейки поверх проблемного контента. Мы реализуем многоуровневую систему модерации: клиентская on-device проверка, серверный AI, асинхронный ревью и хэш-база известного контента. Такой подход исключает ложные срабатывания и минимизирует стоимость обработки. Например, в одном из проектов с UGC-приложением для фитнеса комбинация методов позволила снизить затраты на серверную модерацию на 40% и сократить время реакции на жалобы пользователей с 12 часов до 5 минут.
Почему нельзя полагаться только на одну проверку
Единственный слой — хэш-сравнение PhotoDNA — хорош для детекции известного контента, но не нового. Единственный слой — Vision API — можно обойти лёгкой обработкой изображения. Только комбинация методов даёт защиту. Наш опыт показывает: при совместном использовании клиентской и серверной проверок точность достигает 99,2% при пороге 80% уверенности.
Как работает клиентская проверка: CoreML NudeNet
На iOS VNClassifyImageRequest содержит категории типа explicit, но они недостаточно точны. Лучший on-device вариант — CoreML модель класса NudeNet-mobile (открытая, ~8 MB). Время инференса — 30–50 ms на iPhone 13. Применяем ДО загрузки на сервер: если клиентская модель блокирует — не тратим bandwidth и деньги на серверную проверку.
class LocalImageModerator {
private let model: NudeNetMobile
func check(_ image: CGImage) throws -> LocalModerationResult {
let resized = resize(image, to: CGSize(width: 320, height: 320))
let input = NudeNetInput(image: MLMultiArray(from: resized))
let output = try model.prediction(input: input)
// Классы: SAFE / EXPOSED_BREAST / EXPOSED_GENITALIA / etc.
let topClass = output.classLabels.max(by: { output.classProbability[$0]! < output.classProbability[$1]! })!
return LocalModerationResult(
isSafe: topClass == "SAFE",
confidence: output.classProbability[topClass]!
)
}
}
Пошаговая настройка CoreML модерации
- Скачайте модель NudeNet-mobile из репозитория NudeNet и добавьте .mlmodel в Xcode проект.
- Создайте класс
LocalImageModerator, как в примере выше. - В
ContentViewперед отправкой изображения на сервер вызовитеcheck()и обработайте результат. - Если
confidenceпревышает порог (например, 0.6), покажите пользователю сообщение и не отправляйте изображение.
Почему клиентская проверка экономит бюджет
Каждая отправка изображения на сервер стоит денег (API вызовы, хранение, обработка). Клиентская фильтрация отсекает до 60% неподходящих фото ещё на устройстве. Это снижает нагрузку на бэкенд и уменьшает счета за AWS Rekognition или Google Cloud Vision. При высоком трафике экономия составляет 30–40% от общих затрат на модерацию.
Сравнение серверных решений: AWS Rekognition vs Google Cloud Vision
| Параметр | AWS Rekognition | Google Cloud Vision Safe Search |
|---|---|---|
| Категории модерации | 10+ иерархических меток (Explicit Nudity, Violence, Hate) | 5 меток (adult, violence, racy, spoof, medical) |
| Точность на тестовой выборке | 94% | 92% |
| Скорость ответа (средняя) | 300 ms | 350 ms |
| Стоимость за 1000 изображений | доли цента | доли цента |
| Интеграция с мобильными SDK | через Amplify | через Firebase ML |
Одно из решений лучше другого в зависимости от требуемых категорий и экосистемы. AWS Rekognition выигрывает по количеству меток, Google — по интеграции с Firebase.
Серверная модерация: AWS Rekognition
AWS Rekognition DetectModerationLabels — стандарт для промышленных систем. Хорошая точность, поддержка иерархических меток. Мы используем порог MinConfidence=60 и блокируем контент при уверенности >80% по категориям Explicit Nudity, Violence, Visually Disturbing.
# Backend
import boto3
rekognition = boto3.client('rekognition', region_name='eu-west-1')
def moderate_image(s3_bucket: str, s3_key: str) -> ModerationResult:
response = rekognition.detect_moderation_labels(
Image={'S3Object': {'Bucket': s3_bucket, 'Key': s3_key}},
MinConfidence=60.0
)
labels = response['ModerationLabels']
top_level = [l for l in labels if not l.get('ParentName')]
blocked_categories = {'Explicit Nudity', 'Violence', 'Visually Disturbing'}
for label in top_level:
if label['Name'] in blocked_categories and label['Confidence'] > 80:
return ModerationResult(blocked=True, reason=label['Name'],
confidence=label['Confidence'])
return ModerationResult(blocked=False)
Как настроить порог уверенности в AWS Rekognition
Параметр MinConfidence определяет минимальный уровень уверенности для возврата метки. Мы используем порог 60% для предварительной фильтрации и 80% для автоматической блокировки. According to AWS documentation, более высокие пороги снижают количество ложных срабатываний, но могут пропустить часть нежелательного контента.
Технические детали PhotoDNA и перцептивного хэша
PhotoDNA — проприетарный SDK от Microsoft для [перцептивного хэширования](https://en.wikipedia.org/wiki/Perceptual_hashing). Он устойчив к атакам на размер, сжатие, цветокоррекцию. Хэш генерируется на сервере и сравнивается с базой NCMEC. Альтернатива — open-source библиотека pHash для языка Kotlin. Пример вычисления 64-битного хэша:// Android: pHash через dcperceptualhash
fun computePHash(bitmap: Bitmap): Long {
val scaled = Bitmap.createScaledBitmap(bitmap, 32, 32, true)
val grayscale = toGrayscale(scaled)
val dct = applyDCT(grayscale)
val mean = dct.average()
return dct.foldIndexed(0L) { i, acc, v -> if (v > mean) acc or (1L shl i) else acc }
}
// Hamming distance <= 10 = похожие изображения
fun hammingDistance(a: Long, b: Long): Int = java.lang.Long.bitCount(a xor b)
PhotoDNA / Hash-based детекция CSAM
Для приложений с публичным UGC — юридическое требование в ряде юрисдикций. Microsoft PhotoDNA SDK — перцептивный хэшинг, устойчивый к обрезке, масштабированию и сжатию. Хэш сравнивается с базой известного контента (NCMEC или IWF). Мы также внедряем open-source pHash для дедупликации.
Что входит в работу
- Клиентские модули под iOS (Swift/CoreML) и Android (Kotlin/TensorFlow Lite) с on-device проверкой.
- Серверный API интеграция с AWS Rekognition, Google Cloud Vision или Azure.
- Хэш-база PhotoDNA и/или перцептивный хэш.
- Асинхронная очередь (SQS/RabbitMQ) для ретроактивного ревью.
- Система апелляций и аналитика модерации.
- Документация, инструкции по развёртыванию, обучение команды.
- Поддержка 30 дней после запуска.
Асинхронная проверка и ретроактивное удаление
Синхронная модерация при загрузке — необходима, но недостаточна. Добавляем асинхронную:
- Изображение прошло синхронную проверку → опубликовано.
- Асинхронно: более тяжёлая модель (GPT-4 Vision, дорогой endpoint) перепроверяет.
- Если флаг — контент помечается для ручной проверки или автоудаляется.
Для высоконагруженных приложений — отдельная очередь SQS/RabbitMQ, worker-процессы.
UX при блокировке
Пользователь должен понимать, почему фото отклонено, и иметь возможность обжаловать:
// iOS: показываем экран с причиной и кнопкой аппеляции
struct ModerationRejectionView: View {
let reason: ModerationReason
var body: some View {
VStack {
Image(systemName: "exclamationmark.triangle")
Text("Фото не соответствует правилам сообщества")
Text(reason.userFriendlyDescription)
.foregroundStyle(.secondary)
Button("Обжаловать") { /* открыть форму аппеляции */ }
Button("Выбрать другое фото") { /* dismiss */ }
}
}
}
Аппеляция — форма с текстовым полем, идёт в систему тикетов для ручной модерации. Отвечаем в течение 24–48 часов.
Сроки и стоимость
Ориентировочные сроки:
| Этап | Длительность |
|---|---|
| Backend с Rekognition + клиентский pre-check | 4–6 дней |
| Полная система (с хэш-базой, асинхронным ревью, апелляциями) | 3–4 недели |
| Настройка порогов и A/B тестирование | 5–7 дней |
Стоимость рассчитывается индивидуально: зависит от объёма контента, требований к точности и SLA. Мы гарантируем оптимизацию — снижение затрат на серверную модерацию на 30–40% за счёт клиентского pre-check.
Почему стоит довериться нам
5+ лет на рынке мобильной разработки, 10+ проектов с AI-модерацией, сертифицированные инженеры AWS и Google Cloud. Свяжитесь с нами, чтобы получить консультацию по внедрению системы модерации. Закажите технический аудит вашего текущего решения — мы проанализируем архитектуру и предложим оптимизации.







