diff --git a/tfjs-core/benchmarks/index.html b/tfjs-core/benchmarks/index.html index 5211d63b771..73afdccff83 100644 --- a/tfjs-core/benchmarks/index.html +++ b/tfjs-core/benchmarks/index.html @@ -50,36 +50,9 @@

TensorFlow.js Model Benchmark

-
-
Number of tensors
-
-
-
- - - -
-
-
-
Number of bytes used
-
-
-
- - - -
-
- - - - - - - - +
KernelTime(ms)InputsOutputGPUPrograms
@@ -105,11 +78,15 @@

TensorFlow.js Model Benchmark

runBenchmark(); }, backend: 'wasm', + kernelTiming: 'aggregate', }; const modalDiv = document.getElementById('modal-msg'); const timeTable = document.querySelector('#timings tbody'); const envDiv = document.getElementById('env'); + const kernelsTableHead = document.getElementById('kernels-thead'); + const kernelTable = document.querySelector('#kernels tbody'); + let model, predict, chartWidth; async function showMsg(message) { @@ -137,6 +114,22 @@

TensorFlow.js Model Benchmark

} `; } + async function setupTable() { + kernelsTableHead.innerText = ''; + kernelTable.innerHTML = ''; + await tf.nextFrame(); + const rows = ['Kernel', 'Time(ms)']; + if (state.kernelTiming === 'individual') { + rows.push('Inputs', 'Output'); + if (state.backend === 'webgl') { + rows.push('GPUPrograms'); + } + } + appendRow(kernelsTableHead, ...rows); + + await tf.nextFrame(); + } + function appendRow(tbody, ...cells) { const tr = document.createElement('tr'); cells.forEach(c => { @@ -173,7 +166,12 @@

TensorFlow.js Model Benchmark

async function loadAndRecordTime(benchmark) { await showMsg('Loading the model'); const start = performance.now(); - model = await benchmark.load(); + if (benchmark.model == null) { + model = await benchmark.load(); + benchmark.model = model; + } else { + model = benchmark.model; + } predict = benchmark.predictFunc(); const elapsed = performance.now() - start; @@ -209,11 +207,11 @@

TensorFlow.js Model Benchmark

chartWidth = document.querySelector("#perf-trendline-container").getBoundingClientRect().width; const times = []; - const numTensors = []; - const numBytes = []; + const numLeakedTensors = []; for (let i = 0; i < state.numRuns; i++) { const start = performance.now(); + const tensorsBefore = tf.memory().numTensors; let res = predict(model); if (res instanceof Promise) { res = await res; @@ -227,22 +225,19 @@

TensorFlow.js Model Benchmark

times.push(performance.now() - start); const memInfo = tf.memory(); - numTensors.push(memInfo.numTensors); - numBytes.push(memInfo.numBytes); + const leakedTensors = memInfo.numTensors - tensorsBefore; + numLeakedTensors.push(leakedTensors); } const forceInferenceTrendYMinToZero = true; populateTrendline(document.querySelector("#perf-trendline-container"), times, forceInferenceTrendYMinToZero, printTime); - populateTrendline(document.querySelector("#mem-trendline-container"), numTensors); - - const forceBytesTrendlineYMinToZero = false; - populateTrendline(document.querySelector("#bytes-trendline-container"), numBytes, forceBytesTrendlineYMinToZero, d => `${(d / 1e6).toPrecision(3)} MB`); await showMsg(null); const average = times.reduce((acc, curr) => acc + curr, 0) / times.length; const min = Math.min(...times); appendRow(timeTable, `Subsequent average(${state.numRuns} runs)`, printTime(average)); appendRow(timeTable, 'Best time', printTime(min)); + appendRow(timeTable, 'Leaked tensors', numLeakedTensors[0]); } async function profileMemory() { @@ -267,12 +262,33 @@

TensorFlow.js Model Benchmark

function showKernelTime(kernels) { const tbody = document.querySelector('#kernels tbody'); - kernels.forEach(k => { - const nameSpan = document.createElement('span'); - nameSpan.setAttribute('title', k.scopes.slice(0, -1).join(' --> ')); - nameSpan.textContent = k.scopes[k.scopes.length - 1]; - appendRow(tbody, nameSpan, k.time.toFixed(2), k.inputs, k.output, k.gpuProgramsInfo); - }); + if (state.kernelTiming === 'individual') { + kernels.forEach(k => { + const nameSpan = document.createElement('span'); + nameSpan.setAttribute('title', k.scopes.slice(0, -1).join(' --> ')); + nameSpan.textContent = k.scopes[k.scopes.length - 1]; + appendRow(tbody, nameSpan, k.time.toFixed(2), k.inputs, k.output, k.gpuProgramsInfo); + }); + } else { + const kernelTotalTime = {}; + kernels.forEach(k => { + const kernelName = k.scopes[0]; + if (kernelTotalTime[kernelName] == null) { + kernelTotalTime[kernelName] = 0; + } + kernelTotalTime[kernelName] += k.time; + }); + + const result = Object.keys(kernelTotalTime) + .map(k => [k, kernelTotalTime[k]]) + .sort((a, b) => b[1] - a[1]); + result.forEach(r => { + const nameSpan = document.createElement('span'); + nameSpan.setAttribute('title', r[0]); + nameSpan.textContent = r[0]; + appendRow(tbody, nameSpan, r[1].toFixed(2)); + }); + } } async function profileKernelTime() { @@ -330,6 +346,7 @@

TensorFlow.js Model Benchmark

async function runBenchmark() { const benchmark = benchmarks[state.benchmark]; + await setupTable(); await loadAndRecordTime(benchmark); await warmUpAndRecordTime(); await showMsg('Waiting for GC'); @@ -356,6 +373,7 @@

TensorFlow.js Model Benchmark

gui.add(state, 'backend', ['wasm', 'webgl', 'cpu']).onChange(backend => { tf.setBackend(backend); }); + gui.add(state, 'kernelTiming', ['aggregate', 'individual']); gui.add(state, 'run'); showVersions();