我正在接受人工智能培训,该方法耗时很长(5分钟),而当我的方法运行时,后端保持阻塞,等待方法完成,这有什么解决方案吗?
train: (answersIA, search, res) => {
const path = `api/IA/${search.id}`;
if (answersIA.length == 0) {
return null;
}
else {
answersIA = answersIA.filter(answer => answer.score);
answersIA = answersService.setOutput(answersIA);
answersIA = answersService.encodeAll(IAServiceTrain.adjustSize(answersIA));
net.train(answersIA, {
errorThresh: 0.005,
iterations: 100,
log: true,
logPeriod: 10,
learningRate: 0.3
});
mkdirp(path, (err) => {
if (err) throw 'No permission to create trained-net file';
fs.writeFileSync(`${path}/trained-net.js`, `${net.toFunction().toString()};`);
res.json({
message: 'Trained!'
});
});
}
}
答案 0 :(得分:1)
使用child_process对单独的流程进行培训。这是它的实现方式:
trainMaster.js
const fork = require('child_process').fork;
exports.train = (arguments, callback) => {
const worker = fork(`${__dirname}/trainWorker.js`);
worker.send(arguments);
worker.on('message', result => {
callback(result);
worker.kill();
});
}
trainWorker.js
process.on('message', arguments => {
const result = train(arguments)
process.send(result);
});
function train(arguments) { /* your training logic */ }
因此,当您从主应用程序在 trainMaster.js 上调用train
时,它不会进行实际的训练,也不会阻止事件循环。相反,它创建一个新进程,等待它执行所有繁重的工作,然后终止它。
如果同时训练的数量少于计算机上的CPU数量,则此方法应该可以正常工作。来自Node.js文档:
请务必牢记,生成的Node.js子进程独立于父进程,但两者之间建立的IPC通信通道除外。每个进程都有自己的内存,并带有自己的V8实例。由于需要额外的资源分配,因此不建议生成大量子Node.js进程。
否则,您将需要一些不同的方法,例如将工作人员分布在多台计算机上,并使用消息队列在它们之间分配工作。
答案 1 :(得分:0)
正如https://stackoverflow.com/users/740553/mike-pomax-kamermans所述,Javascript是单线程的,这意味着长时间运行的同步操作将在执行时阻塞您的线程。目前尚不清楚您正在使用哪个库来进行培训,但是请检查它们是否具有用于培训的异步方法。另外,您正在使用fs.writeFile
方法的同步版本,该方法将再次在执行时阻塞您的线程。要解决此问题,请使用异步版本:
fs.writeFile(`${path}/trained-net.js`, `${net.toFunction().toString()};`, function (err) {
if (err) return console.log(err);
console.log('File write completed');
}););