我想通过importScripts()如下导入webWorker中的2个脚本,但是导入失败。如何处理?
self.importScripts('https://cdn.jsdelivr.net/npm/@tensorflow/tfjs');
self.importScripts('https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-converter');
答案 0 :(得分:2)
当前,无法在web-worker上使用webgl实现,offlineCanvas是实验性功能。但是,可以使用CPU后端。
这里是委派给网络工作者执行计算的示例
<head>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.14.2/dist/tf.min.js"></script>
<script>
const worker_function = () => {
onmessage = () => {
console.log('from web worker')
this.window = this
importScripts('https://cdn.jsdelivr.net/npm/setimmediate@1.0.5/setImmediate.min.js')
importScripts('https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.10.3')
tf.setBackend('cpu')
const res = tf.zeros([1, 2]).add(tf.ones([1, 2]))
res.print()
postMessage({res: res.dataSync(), shape: res.shape})
};
}
if (window != self)
worker_function();
</script>
<script>
const worker = new Worker(URL.createObjectURL(new Blob(["(" + worker_function.toString() + ")()"], { type: 'text/javascript' })));
worker.postMessage({});
worker.onmessage = (message) => {
console.log('from main thread')
const {data} = message
tf.tensor(data.res, data.shape).print()
}
</script>
</head>
使用张量,在主线程和Web Worker之间共享的数据可能很大。可以克隆或传输此数据。
区别在于,如果克隆了数据,Web Worker将仍然保留数据的副本以进行进一步处理。传输时,数据的所有权也会被传输。与克隆相比,它的优点是传输速度快,实际上它可以看作是引用的传递(如果引用来自具有指针语言的背景)
让我们用这两个片段讨论性能
<head>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.14.2/dist/tf.min.js"></script>
<script>
const worker_function = () => {
onmessage = () => {
console.log('from web worker')
this.window = this
importScripts('https://cdn.jsdelivr.net/npm/setimmediate@1.0.5/setImmediate.min.js')
importScripts('https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.10.3')
tf.setBackend('cpu')
const res = tf.randomNormal([2000, 2000, 3])
const t0 = performance.now()
postMessage({res: res.dataSync().buffer, shape: res.shape}, [res.dataSync().buffer])
console.log(`Prediction took ${(performance.now() - t0).toFixed(1)} ms`)
};
}
if (window != self)
worker_function();
</script>
<script>
const worker = new Worker(URL.createObjectURL(new Blob(["(" + worker_function.toString() + ")()"], { type: 'text/javascript' })));
worker.postMessage({});
worker.onmessage = (message) => {
console.log('from main thread')
const {data} = message
tf.tensor(new Float32Array(message.data.res), message.data.shape)
}
</script>
</head>
<head>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.14.2/dist/tf.min.js"></script>
<script>
const worker_function = () => {
onmessage = () => {
console.log('from web worker')
this.window = this
importScripts('https://cdn.jsdelivr.net/npm/setimmediate@1.0.5/setImmediate.min.js')
importScripts('https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.10.3')
tf.setBackend('cpu')
const res = tf.randomNormal([2000, 2000, 3])
const t0 = performance.now()
postMessage({res: res.dataSync(), shape: res.shape})
console.log(`Prediction took ${(performance.now() - t0).toFixed(1)} ms`)
};
}
if (window != self)
worker_function();
</script>
<script>
const worker = new Worker(URL.createObjectURL(new Blob(["(" + worker_function.toString() + ")()"], { type: 'text/javascript' })));
worker.postMessage({});
worker.onmessage = (message) => {
console.log('from main thread')
const {data} = message
tf.tensor(message.data.res, message.data.shape)
}
</script>
</head>
我们可以看到两个摘要之间相差约10毫秒。如果以性能为代价,那么必须克隆或传输数据时,应考虑如何共享数据。
答案 1 :(得分:0)
TensorflowJS需要画布来执行GPU计算,并且工作人员当前没有画布。
OffscreenCanvas是一项正在使用的功能,但是在TFJS使用它之前,它可能需要足够广泛的浏览器支持。