Sentis — ML inference в Unity
ONNX-модели в реальном времени, IWorker, практический пример классификации изображения.
Sentis — встроенная в Unity 6 система для выполнения машинного обучения в реальном времени внутри игры. Заменил Barracuda (deprecated с 2023).
Что можно с Sentis:
- Классификация изображений с камеры (ResNet, MobileNet, YOLO).
- NPC AI на нейросетях (decision-making, dialog generation).
- Style transfer для post-process эффектов.
- Pose estimation для motion capture без датчиков.
- Voice command recognition.
Установка и базовая идея
- Package Manager → установите Sentis (
com.unity.sentis). С Unity 6.1 — официально GA. - Импортируйте
.onnx-файл (ONNX — открытый формат экспорта моделей из PyTorch, TensorFlow и др.) как обычный ассет. Unity автоматически распознаёт и конвертирует. - В коде используете
ModelLoader.Load(modelAsset)→Worker→worker.Schedule(input)→worker.PeekOutput().
transformers.js от Hugging Face — запуск моделей в браузере через ONNX Runtime Web.
Sentis — то же концептуально, но native через compute shaders, без WebAssembly overhead.
Sentis под капотом — GPU compute shaders (опционально CPU). Inference 60+ FPS для маленьких моделей на потребительском железе. Один Worker — один runtime для одной модели; создаёте на время загрузки.
Полный пример: классификация изображения
Возьмём MobileNetV2 — лёгкая модель, классифицирует картинку 224×224 в одну из 1000 категорий (ImageNet).
Подготовка
- Скачайте
mobilenetv2.onnx(например, с ONNX Model Zoo). - Перетащите в
Assets/— появитсяModelAsset. - Создайте labels.txt со 1000 строк-категорий (классы ImageNet).
Скрипт
using System.Collections.Generic;
using System.Linq;
using Unity.Sentis;
using UnityEngine;
public class ImageClassifier : MonoBehaviour
{
[SerializeField] private ModelAsset modelAsset;
[SerializeField] private TextAsset labels; // labels.txt
[SerializeField] private Camera sourceCamera;
[SerializeField] private RenderTexture cameraOutput;
private Worker _worker;
private Model _model;
private string[] _classes;
private void Awake() {
_model = ModelLoader.Load(modelAsset);
_worker = new Worker(_model, BackendType.GPUCompute);
_classes = labels.text.Split('\n').Select(s => s.Trim()).ToArray();
}
private void OnDestroy() {
_worker?.Dispose();
}
public void Classify() {
// 1. Преобразуем картинку (RenderTexture) → Tensor 1×3×224×224 (NCHW)
using var input = TextureConverter.ToTensor(cameraOutput, width: 224, height: 224, channels: 3);
// 2. Запускаем модель
_worker.Schedule(input);
// 3. Читаем output (1×1000 — confidence для каждого класса)
using var output = (_worker.PeekOutput() as Tensor<float>).ReadbackAndClone();
// 4. Находим argmax
int bestIdx = 0;
float bestVal = output[0];
for (int i = 1; i < output.shape[1]; i++) {
if (output[0, i] > bestVal) {
bestVal = output[0, i];
bestIdx = i;
}
}
Debug.Log($"Detected: {_classes[bestIdx]} (confidence: {bestVal:F3})");
}
private void Update() {
if (Input.GetKeyDown(KeyCode.Space)) {
Classify();
}
}
}
При нажатии Space скрипт берёт картинку с камеры (cameraOutput — RenderTexture, в которую sourceCamera
рендерит), прогоняет через модель и выводит наиболее вероятный класс.
Backend selection — GPU vs CPU
Worker принимает BackendType:
| Backend | Когда |
|---|---|
BackendType.GPUCompute | Default. Compute shaders, быстро на современных GPU. |
BackendType.GPUPixel | Fallback для GPU без compute shader (старый WebGL). |
BackendType.CPU | Когда нет GPU или нужен deterministic output (для replay-системы). |
Производительность для MobileNetV2 224×224 на NVIDIA GTX 1060:
- GPUCompute: ~5 мс
- CPU: ~50 мс
Tensor — input/output формат
Sentis работает с типом Tensor<float> (или Tensor<int>). У него есть shape — массив размерностей.
Для NCHW (стандартный image format):
N= batch size (обычно 1 для real-time)C= каналы (3 для RGB)H,W= высота × ширина
// Создать тензор из массива
var tensor = new Tensor<float>(new TensorShape(1, 3, 224, 224));
for (int i = 0; i < tensor.count; i++) {
tensor[i] = Random.value;
}
// Или из Texture / RenderTexture
var tex = TextureConverter.ToTensor(rt);
Важно: Tensor реализует IDisposable. Если забыли .Dispose(), утечка GPU-памяти.
Использование в game logic
Распространённые паттерны:
NPC decision-making
NN модель принимает вектор “состояния игры” и возвращает action. Pre-trained reinforcement learning из ML-Agents → экспорт в ONNX → импорт в shipping-build.
Style transfer на видео
Применить художественный стиль (e.g., Ghibli, oil painting) к рендеру камеры в реальном времени. Sentis запускает StyleGAN-подобную модель на каждый кадр.
Speech-to-text
Whisper или подобная модель → конвертация микрофонного ввода в текст для voice commands.
Image-based AI
Захват изображения с камеры (AR-режим) → определение объектов через YOLO → размещение виртуальных объектов рядом с реальными.
Большие модели (несколько сотен МБ) inference часто стоит >16.6 мс на кадр — игра тормозит. Решения:
- Использовать меньшую модель (MobileNet вместо ResNet).
- Запускать раз в N кадров, а не каждый — для NPC decision-making достаточно 5 FPS.
- Quantize модель до int8 (если ML-фреймворк поддерживает).
- Async inference через
worker.ScheduleAsync(возвращает Promise-like).
Async inference
public async Awaitable ClassifyAsync(RenderTexture input) {
using var tensor = TextureConverter.ToTensor(input, 224, 224, 3);
_worker.Schedule(tensor);
// Ждём, пока GPU закончит — не блокируем main thread
using var output = (_worker.PeekOutput() as Tensor<float>);
await output.ReadbackRequestAsync();
using var cpu = output.ReadbackAndClone();
// Обрабатываем результат
}
ReadbackRequestAsync ждёт асинхронно без главного потока — игра продолжает рендериться.
Где брать модели
- ONNX Model Zoo — официальный репо с готовыми моделями (classification, detection, NLP).
- Hugging Face — гигантская библиотека. Часто поставляются с PyTorch — экспортируете в ONNX
через
torch.onnx.export(). - Unity AI Hub — Unity collection моделей, оптимизированных для Sentis.
- Custom training: тренируете в PyTorch/TensorFlow → экспорт в ONNX → импорт в Unity.
Ограничения Sentis
- Не все операторы поддержаны — некоторые экзотические слои (custom CUDA-операции) не работают.
- Dynamic shapes ограничены — Sentis предпочитает fixed input size (хорошо для большинства game ML-моделей).
- Memory footprint — большие модели жрут VRAM. Профайлите.
- WebGL — работает, но медленно (GPU compute shaders в браузере = WebGPU only).
Сравнение с альтернативами
| Sentis | ML-Agents | TorchSharp | |
|---|---|---|---|
| Назначение | Production inference | Training agents | General .NET ML |
| Backend | GPU compute / CPU | PyTorch (training) | LibTorch native |
| Размер | Light | Heavy | Heavy |
| Integration с Unity | Native | Native | Manual |
ML-Agents используют для тренировки RL-агентов, Sentis — для запуска результирующей модели. Это разные фазы пайплайна.