Universal Sentence Encoder tensorflowjs 使用 webworker 优化性能

Nir*_*mal 5 javascript web-worker word-embedding tensorflow.js

我正在使用以下代码启动 Webworker,它使用 Universal Sentence Encoder 创建嵌入

const initEmbeddingWorker = (filePath) => {
    let worker = new Worker(filePath);
    worker.postMessage({init: 'init'})

    worker.onmessage = (e) => {
        worker.terminate();
    }
}
Run Code Online (Sandbox Code Playgroud)

网络工作者代码

onmessage = function (e) {
    if(e.data.init && e.data.init === 'init') {
        fetchData();
    }
}

const fetchData = () => {
    //fetches data from indexeddb
    createEmbedding(data, storeEmbedding);
}

const createEmbedding = (data, callback) => {
    use.load().then(model => {
        model.embed(data).then(embeddings => {
            callback(embeddings);
        })
    });
}

const storeEmbedding = (matrix) => {
    let data = matrix.arraySync();
    //store data in indexeddb
}
Run Code Online (Sandbox Code Playgroud)

使用 10 个同时运行的 Webworker 创建 100 个嵌入需要 3 分钟,每个 worker 为 10 个句子创建嵌入。创建嵌入所需的时间太长,因为我需要为 1000 多个句子创建嵌入,大约需要 25 到 30 分钟。每当此代码运行时,它都会占用所有资源,这使得机器非常缓慢且几乎无法使用。

是否缺少任何性能优化?

edk*_*ked 0

使用 10 个 webworker 意味着用于运行它的机器至少有 11 个核心。为什么有这个假设?(webworker数量+主线程)

为了充分利用 webworker,每个 webworker 应该在不同的核心上运行。当工人数量多于核心数量时会发生什么?嗯,程序不会像预期的那么快,因为很多时候将用于在内核之间交换通信。

现在让我们看看每个核心上发生了什么。

arraySync是阻止该线程用于其他事情的阻塞调用。

代替使用arraySyncarray可以使用 。

const storeEmbedding = async (matrix) => {
    let data = await matrix.array();
    //store data in indexeddb
}
Run Code Online (Sandbox Code Playgroud)

array与和arraySync相比,其对应项速度较慢。最好存储扁平化数据,输出。datadataSyncdata

const storeEmbedding = async (matrix) => {
        let data = await matrix.data();
        //store data in indexeddb
    }
Run Code Online (Sandbox Code Playgroud)