当我使用node.js并表达

时间:2018-08-02 05:47:10

标签: node.js express tensorflow.js

问题

不好意思。
我使用tensorflow-models / posenet(https://github.com/tensorflow/tfjs-models/tree/master/posenet),node.js(https://github.com/tensorflow/tfjs-node)和express(https://github.com/expressjs/express)实现了演示应用。
我按以下方式替换了示例代码,但是执行estimateMultiplePoses()(https://github.com/tensorflow/tfjs-models/blob/master/posenet/src/posenet_model.ts)时GPU可能无法工作。
你能告诉我如何在GPU上运行代码吗?

例如,当我将API发布到本地服务器时,响应非常低。

$curl -X POST -F thumbnail=@./picture.png localhost:3000/upload

[在服务器日志中]
我希望响应时间少于100毫秒。
当我不使用PoseNet API时,响应时间不到30毫秒,因此以为响应速度很慢是由于未在GPU上运行引起的。

POST /upload 200 2110.888 ms - 9372

但是,构建服务器时该过程可能仍然存在。

$ nvidia-smi
Tue Jul 31 10:27:38 2018       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 396.37                 Driver Version: 396.37                    |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce GTX 107...  On   | 00000000:01:00.0  On |                  N/A |
| 27%   40C    P8    13W / 180W |   7732MiB /  8116MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   1  GeForce GTX 107...  On   | 00000000:02:00.0 Off |                  N/A |
| 27%   38C    P8    12W / 180W |   7723MiB /  8119MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0      1252      G   /usr/lib/xorg/Xorg                           281MiB |
|    0      2068      G   compiz                                       226MiB |
|    0      2435      G   ...-token=...                                 61MiB |
|    0      2697      G   unity-control-center                          15MiB |
|    0      2945      G   ...-token=...                                 92MiB |
|    0     14062      G   ...-token=...                                 66MiB |
|    0     26892      C   node                                        6983MiB |
|    1     26892      C   node                                        7711MiB |
+-----------------------------------------------------------------------------+

致谢。


自定义代码

./ routes / index.js

var posenet = require('@tensorflow-models/posenet');
var tf = require('@tensorflow/tfjs');
require('@tensorflow/tfjs-node-gpu');

var express = require('express');
var router = express.Router();
var multer = require('multer');
var upload = multer({dest: "./uploads/"}).single('thumbnail');
var Canvas = require('canvas');
var Image = Canvas.Image;

const state = {
  input: {
    imageScaleFactor: 0.5,
    flipHorizontal: false,
    outputStride: 16,
  },
  detection: {
    maxPoseDetections: 5,
    minPoseConfidence: 0.15,
    minPartConfidence: 0.1,
    nmsRadius: 30.0,
  },
};

function createHTMLCanvasElementFromRequest(req){
    const img = new Image;
    img.src = req.file.path;
    const canvas = new Canvas(img.width,img.height); 
    const ctx = canvas.getContext('2d');
    ctx.drawImage(img, 0, 0, img.width, img.height);
    return canvas;
}

function detectPoses(req, res){
  const canvas = createHTMLCanvasElementFromRequest(req);
  async function usePoseNet(req){
    const net = await posenet.load();
    const poses = await net.estimateMultiplePoses(  canvas, 
                                                  state.input.imageScaleFactor, 
                                                  state.input.flipHorizontal, 
                                                  state.input.outputStride, 
                                                  state.detection.maxPoseDetections,
                                                  state.detection.minPartConfidence, 
                                                  state.detection.nmsRadius);
    return poses;
  }
  usePoseNet(req).then( json_res =>{
    res.send({
        "OriginalName": req.file.originalname,
        "FileName": req.file.filename,
        "Size": req.file.size,
        "Width": canvas.width,
        "Height": canvas.height,
        "Context": json_res
    })
  }).catch(e => {
    res.send({
        "Error": e
    });
  });
}

function failedToGetImages(req,res, err){
  res.send({
        "Destination": req.file.destination,
        "Error": err
      });
}

router.post('/upload', function(req, res){
  upload(req, res, function(err){
    res.header('Content-Type', 'application/json; charset=utf-8');
    err? failedToGetImages(req,res,err) : detectPoses(req, res);
  });
});

module.exports = router;

./ app.js

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

var indexRouter = require('./routes/index');

var app = express();

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');

app.use(logger('dev'));
app.use(express.json());
app.use(cookieParser());
app.use(express.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', indexRouter);

app.use(function (req, res, next) {
  res.header('Access-Control-Allow-Origin', req.headers.origin);
  res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
  res.header('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS');
  res.header('Access-Control-Allow-Credentials', true);
  res.header('Access-Control-Max-Age', '86400');
  next();
});

app.options('*', function (req, res) {
  res.sendStatus(200);
});


// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});


module.exports = app;

./ bin / www

#!/usr/bin/env node

var app = require('../app');
var debug = require('debug')('roboserver:server');
var http = require('http');

var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

var server = http.createServer(app);

server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

function normalizePort(val) {
  var port = parseInt(val, 10);

  if (isNaN(port)) {
    return val;
  }

  if (port >= 0) {
    return port;
  }

  return false;
}

function onError(error) {
  if (error.syscall !== 'listen') {
    throw error;
  }

  var bind = typeof port === 'string'
    ? 'Pipe ' + port
    : 'Port ' + port;

  // handle specific listen errors with friendly messages
  switch (error.code) {
    case 'EACCES':
      console.error(bind + ' requires elevated privileges');
      process.exit(1);
      break;
    case 'EADDRINUSE':
      console.error(bind + ' is already in use');
      process.exit(1);
      break;
    default:
      throw error;
  }
}

function onListening() {
  var addr = server.address();
  var bind = typeof addr === 'string'
    ? 'pipe ' + addr
    : 'port ' + addr.port;
  debug('Listening on ' + bind);
}

系统信息

  • OS平台和发行版:ubuntu 16.04.4 LTS
  • 通过以下方式安装的TensorFlow:https://github.com/tensorflow/tfjs
  • TensorFlow版本:0.12.0
  • CUDA / cuDNN:8.0 / 6.0
  • GPU型号:GeForce GTX 1070 Ti 8GB * 2
  • 内存:

    存在SMBIOS 3.0.0。 句柄0x0043,DMI类型16,23字节 物理内存阵列     位置:系统板或主板     用途:系统内存     错误纠正类型:无     最大容量:32 GB     错误信息句柄:未提供     设备数量:2

    句柄0x0044,DMI类型17,40字节 存储设备     数组句柄:0x0043     错误信息句柄:未提供     总宽度:未知     数据宽度:未知     大小:未安装模块     外形尺寸:未知     设置:无     定位器:ChannelA-DIMM1     银行定位器:BANK 0     类型:未知     类型详细信息:无     速度:未知     制造商:未指定     序列号:未指定     资产标签:未指定     零件编号:未指定     排名:未知     配置的时钟速度:未知     最低电压:未知     最大电压:未知     配置电压:未知

    句柄0x0045,DMI类型17,40字节 存储设备     数组句柄:0x0043     错误信息句柄:未提供     总宽度:64位     资料宽度:64位     大小:16384 MB     规格:DIMM     设置:无     定位器:ChannelA-DIMM2     银行定位器:BANK 1     类型:DDR4     类型详细信息:同步未缓冲(未注册)     速度:2133 MHz     制造商:海盗船     序列号:00000000     资产标签:9876543210     零件编号:CMK32GX4M2B3000C15
        等级:2     配置的时钟速度:2133 MHz     最低电压:未知     最大电压:未知     设定电压:1.2 V

    句柄0x0046,DMI类型17,40字节 存储设备     数组句柄:0x0043     错误信息句柄:未提供     总宽度:未知     数据宽度:未知     大小:未安装模块     外形尺寸:未知     设置:无     定位器:ChannelB-DIMM1     银行定位器:BANK 2     类型:未知     类型详细信息:无     速度:未知     制造商:未指定     序列号:未指定     资产标签:未指定     零件编号:未指定     排名:未知     配置的时钟速度:未知     最低电压:未知     最大电压:未知     配置电压:未知

    句柄0x0047,DMI类型17,40字节 存储设备     数组句柄:0x0043     错误信息句柄:未提供     总宽度:64位     资料宽度:64位     大小:16384 MB     规格:DIMM     设置:无     定位器:ChannelB-DIMM2     银行定位器:BANK 3     类型:DDR4     类型详细信息:同步未缓冲(未注册)     速度:2133 MHz     制造商:海盗船     序列号:00000000     资产标签:9876543210     零件编号:CMK32GX4M2B3000C15
        等级:2     配置的时钟速度:2133 MHz     最低电压:未知     最大电压:未知     配置电压:1.2 V

  • 要复制的精确命令:节点./bin/www

  • 浏览器:谷歌浏览器
  • npm:6.1.0
  • 节点:10.6.0
  • @ tensorflow-models / posenet:0.2.2
  • @ tensorflow / tfjs-node:0.1.9
  • @ tensorflow / tfjs-node-gpu:0.1.9
  • gcc:5.4.0

0 个答案:

没有答案