Работа с ONNX Runtime Web в JavaScript нередко сопровождается
ситуациями, когда модель возвращает значения NaN (Not a
Number) или Inf (Infinity) в выходных тензорах. Такие
значения могут свидетельствовать о нестабильности модели, ошибках данных
или некорректной настройке вычислений. Понимание их происхождения и
эффективная диагностика критически важны для обеспечения корректного
функционирования приложений.
1. Некорректные входные данные
undefined или null в
тензорах.2. Ошибки модели или её конфигурации
exp, log, div).float32 vs
float64).3. Особенности выполнения в браузере
1. Использование функций проверки JavaScript
Для проверки отдельных элементов тензора применяются стандартные методы:
function hasNaN(tensorData) {
return tensorData.some(x => Number.isNaN(x));
}
function hasInf(tensorData) {
return tensorData.some(x => !Number.isFinite(x));
}
При больших тензорах стоит использовать TypedArray
методы для оптимизации:
const data = outputTensor.data;
const hasNaN = data.some(Number.isNaN);
const hasInf = data.some(x => !Number.isFinite(x));
2. Отладка на уровне сессии ONNX Runtime
ONNX Runtime Web предоставляет возможность отладки сессий и слоёв модели:
const session = await ort.InferenceSession.create('model.onnx', { executionProviders: ['wasm'] });
const feeds = { input: new ort.Tensor('float32', inputData, inputShape) };
const results = await session.run(feeds);
console.log(results.outputTensor.data.slice(0, 10));
Вывод первых элементов помогает определить, на каком шаге появляются некорректные значения.
1. Разделение входов и слоёв
nodejs для детальной трассировки).2. Использование промежуточных тензоров
3. Нормализация и масштабирование данных
function normalize(input) {
const max = Math.max(...input);
const min = Math.min(...input);
return input.map(x => (x - min) / (max - min));
}
[minThreshold, maxThreshold] для предотвращения
переполнения.float32 для всех тензоров.log(0) или деление на
ноль).function sanitizeTensorData(data) {
return data.map(x => {
if (Number.isNaN(x)) return 0;
if (!Number.isFinite(x)) return x > 0 ? Number.MAX_VALUE : -Number.MAX_VALUE;
return x;
});
}
const sanitizedData = sanitizeTensorData(outputTensor.data);
const sanitizedTensor = new ort.Tensor('float32', sanitizedData, outputTensor.dims);
Такой подход предотвращает распространение некорректных значений на последующие вычисления.
console.table или графических библиотек
для визуального контроля распределения значений.const stats = {
max: Math.max(...outputTensor.data),
min: Math.min(...outputTensor.data),
NaN_count: outputTensor.data.filter(Number.isNaN).length,
Inf_count: outputTensor.data.filter(x => !Number.isFinite(x)).length
};
console.table(stats);
wasm или
webgl) позволяет сравнивать результаты и выявлять
платформенные особенности.const sessionWASM = await ort.InferenceSession.create('model.onnx', { executionProviders: ['wasm'] });
const sessionWebGL = await ort.InferenceSession.create('model.onnx', { executionProviders: ['webgl'] });
Сравнение выходов помогает локализовать источник некорректных значений.