В библиотеке TensorFlow.js tf.time предоставляет мощный
инструмент для измерения времени выполнения операций и оценки
производительности модели или отдельных вычислительных блоков. Он
особенно полезен при оптимизации кода и анализе узких мест в вычислениях
на CPU или GPU.
tf.timeМетод tf.time принимает на вход функцию, внутри которой
выполняются тензорные операции TensorFlow.js. Результатом вызова
является объект с двумя основными свойствами:
kernelMs — время выполнения
низкоуровневых операций (ядровых функций) в миллисекундах. Этот
показатель отражает реальное время, затраченное на вычисления
тензоров.wallMs — «стеновое» время, общее время
выполнения всей функции, включая накладные расходы JavaScript и
асинхронную обработку. Обычно wallMs чуть больше
kernelMs, так как учитывает дополнительные операции
управления.Пример базового использования:
const result = await tf.time(() => {
const a = tf.randomNormal([1000, 1000]);
const b = tf.randomNormal([1000, 1000]);
return tf.matMul(a, b);
});
console.log(`Kernel time: ${result.kernelMs} ms`);
console.log(`Wall time: ${result.wallMs} ms`);
В этом примере создаются два тензора размером 1000×1000 и выполняется их умножение. Время выполнения фиксируется отдельно для ядра и для общей функции.
TensorFlow.js выполняет многие операции асинхронно, особенно на WebGL
и WebGPU. Это означает, что замеры wallMs могут быть
полезны для оценки полной задержки, а kernelMs точнее
отражает нагрузку на GPU или CPU.
При необходимости точного измерения асинхронных операций внутри
tf.time можно использовать tf.nextFrame() для
синхронизации визуализации или завершения вычислений:
await tf.time(async () => {
const x = tf.randomNormal([500, 500]);
const y = tf.randomNormal([500, 500]);
const z = tf.matMul(x, y);
await z.data(); // Принудительное ожидание завершения вычислений
});
Вызов await z.data() гарантирует, что все операции будут
завершены до окончания измерения времени.
tf.time для оптимизацииСравнение разных реализаций операций При создании моделей или вычислительных пайплайнов можно тестировать альтернативные методы реализации и выбирать наиболее быстрые. Например, сравнение последовательного сложения и батчевой операции:
const resultSeq = await tf.time(() => {
let sum = tf.zeros([1000, 1000]);
for (let i = 0; i < 10; i++) {
sum = tf.add(sum, tf.randomNormal([1000, 1000]));
}
return sum;
});
const resultBatch = await tf.time(() => {
const tensors = Array.from({ length: 10 }, () => tf.randomNormal([1000, 1000]));
return tf.addN(tensors);
});
console.log(`Sequential: ${resultSeq.kernelMs} ms, Batch: ${resultBatch.kernelMs} ms`);
Это позволяет выявить, что в большинстве случаев пакетные операции
(tf.addN) выполняются быстрее за счет оптимизации ядра и
меньших накладных расходов JavaScript.
Мониторинг горячих участков кода В больших
моделях можно оборачивать ключевые слои в tf.time для
локальной оптимизации. Например, измерение времени работы слоя
Conv2D:
const convTime = await tf.time(() => {
const input = tf.randomNormal([1, 128, 128, 3]);
const kernel = tf.randomNormal([3, 3, 3, 16]);
return tf.conv2d(input, kernel, 1, 'same');
});
console.log(`Conv2D layer kernel time: ${convTime.kernelMs} ms`);
Такой подход позволяет понять, какие слои или операции создают узкие места в производительности.
tf.time один раз, но для статистически надежных
результатов лучше проводить несколько прогонов и усреднять
значения.tf.time подходит для измерения операций с
тензорами, но не для всего JavaScript-кода. Асинхронные вызовы
вне TensorFlow.js учитываются только в wallMs.kernelMs могут быть меньше, чем
wallMs, из-за асинхронного характера WebGL/WebGPU. Для
точного анализа рекомендуется использовать
await tensor.data() или tensor.array() внутри
замера.tf.time с профилировщиком браузера помогает
выявлять не только вычислительные узкие места, но и узкие места в
управлении памятью.TensorFlow.js также предоставляет tf.profile, который
позволяет измерять использование памяти и количество операций. В
комбинации с tf.time это даёт полное понимание
производительности:
const profile = await tf.profile(() => {
const x = tf.randomNormal([1000, 1000]);
const y = tf.randomNormal([1000, 1000]);
return tf.matMul(x, y);
});
console.log(`Memory usage: ${profile.newBytes} bytes, Kernel time: ${profile.kernelMs} ms`);
Использование tf.time совместно с профайлингом делает
процесс оптимизации моделей прозрачным и управляемым.
tf.time является важным инструментом для точного анализа
производительности TensorFlow.js, позволяя выделять узкие места,
сравнивать подходы и планировать оптимизацию кода для CPU и GPU.