ONNX Runtime Web предоставляет возможность эффективно выполнять модели машинного обучения в браузере и средах на базе JavaScript. Одним из ключевых аспектов оптимизации работы с моделями является обрезка графа (graph pruning) и удаление лишних узлов, которые не влияют на конечный результат. Эти техники позволяют уменьшить время выполнения, сократить объем памяти и ускорить загрузку модели.
ONNX-модель представляет собой направленный ациклический граф (DAG), где узлы — это операции (операторы ONNX), а ребра — тензоры, передающиеся между операциями. В процессе подготовки модели к веб-выполнению часто встречаются:
Dropout или
BatchNormalization, которые могут быть упрощены или
удалены.Удаление этих узлов позволяет сократить граф до минимально необходимого набора операций.
Ключевые шаги:
Анализ зависимостей узлов
Определение корневых узлов
model.graph.output).Рекурсивное удаление
ONNX Runtime Web не предоставляет встроенного интерфейса для прямого
редактирования графа на уровне JavaScript, но поддерживает работу с
оптимизированными моделями и оптимизацию при загрузке
через InferenceSession:
import * as ort from 'onnxruntime-web';
const sessionOptions = {
executionProviders: ['wasm'],
graphOptimizationLevel: 'all' // full optimization, включая обрезку графа
};
const session = await ort.InferenceSession.create('model.onnx', sessionOptions);
Пояснение ключевых параметров:
graphOptimizationLevel
disabled — без оптимизацииbasic — базовые оптимизации, удаление констант и
простой dead codeextended — расширенные оптимизации, включая слияние
узловall — полная оптимизация, включая обрезку
неиспользуемых узловexecutionProviders
wasm,
webgl), что важно при оптимизации для браузера.Для сложных случаев иногда необходимо вручную модифицировать ONNX-граф до передачи в Web. Процесс включает:
Загрузка модели с помощью ONNX.js или Python ONNX
onnx.onnx.ModelProto, где можно получить
доступ к graph.node.Анализ каждого узла
import onnx
mo del = onnx.load("model.onnx")
graph = model.graph
# Сбор всех используемых тензоров
used_tensors = set(output.name for output in graph.output)
for node in reversed(graph.node):
if any(out in used_tensors for out in node.output):
used_tensors.update(node.input)
else:
graph.node.remove(node)
onnx.save(model, "pruned_model.onnx")
Этот пример удаляет все узлы, которые не влияют на выходы модели.
Экспорт оптимизированной модели в Web
ort.InferenceSession.Identity, Dropout и ненужные
константы.graphOptimizationLevel: 'all' для максимальной
автоматической обрезки графа.Удаление лишних узлов:
Этот подход позволяет поддерживать высокую эффективность выполнения ONNX-моделей в браузере, делая их быстрее и экономнее по ресурсам без потери точности прогнозов.