0%

需求

利用Pytorch 训练好模型后,如何在生产环境部署目前还是一个探索中的问题,尚未形成比较统一的方案.
不像TensorFlow有比较好的生态,生产环境中可以将模型放到Serving上.
那为什么不到TensorFlow中进行模型的开发呢?主要是:觉得TensorFlow中开发太慢了,不太熟悉,更喜欢Pytorch.

那么尚没有比较完整生态的Pytorch模型应该怎么部署呢?
主要有几种不同的场景:

  • 客户端部署(例如消费端本地,APP内等)
  • 服务端
  • API封装调用

API封装调用本质上来讲也是服务端部署,只是架构上做了一层分离,更容易scale,但是也可能需要付出更多的通信成本.
除了区分不同场景外,还有几种主要的操作方式,主要有:直接嵌入/模型服务(微服务/C++服务/云端部署/框架部署(MLFlow, Kubeflow, RedisAI,甚至TensorFlow Serving))
几种方式的基本介绍在Pytorch官网有一篇blog,谈了目前推荐的一些方案,可参考.Model Serving in PyTorch(https://pytorch.org/blog/model-serving-in-pyorch/)

背景

针对服务端做了两个尝试:

  • 模型直接嵌入在web框架中(Django)
  • 用C++ 起了一个服务,进行API调用

环境

mbp/Django/python3.6/torch1.1.0
这里可能需要说一下的是,如果torch版本不是最新稳定版本的话,可能需要注意一下,对结果影响也是挺大的.

评价标准

  • 简洁性
  • 速度/并发

其实主要测的还是并发,因为如果速度优势足够大的话牺牲一点简洁性也是可以接受的.

步骤

  • 模型训练

    不在本篇讨论范围内.
    默认得到一个python环境下的模型.
  • C++部署

  • Django嵌入部署

  • 模型直接在服务启动是setting中load
  • 在项目内部调用

结果

其实步骤都比较简单
最关键的其实是我想记录一下测试结果.
原本想着用C++起服务可能会比较快一点,但是结果测下来,发现然而并没有(也有可能是我不熟悉C++的原因).
C++的RPS只能到20左右
Django嵌入可以到50左右.
另外,当然是后者的方式更简洁一些.

再另外,如果需要要在C++中做比较多的处理步骤,可能就会更不方便,比如分词.
所以,如果是图像一类,如果做得合适,还有可能用C++起个服务,但是NLP一类可能会更困难一些.
相对来说,Django嵌入的方式应该简单多了.

再再另外,
模型对系统版本,框架版本,部署线程等其实也挺敏感的,多试几次就好了++,搜索空间也不大.
Ubuntu 16.04/torch1.1.0/ gunicorn

1
torch.set_num_threads(3)

1
gunicorn --env DJANGO_SETTINGS_MODULE=xxxx.settings xxxx.wsgi:application -w 3 -b 0.0.0.0:8001 -k gthread --thread 3 --max-requests 4096 --max-requests-jitter 512 --log-level=debug --timeout 120 --preload

需求

家里有一台Windows PC,我希望能够像连阿里云服务器一样随时随地都可以远程连接,以便充分利用资源.
当然可以利用远程连接软件,比如teamviewer\向日葵 甚至 QQ都可以实现这样的远程控制,
但这不是我最想要的,一是多屏不方便,二是在两个电脑的两个软件之间转来转去也很麻烦.
我最希望的是像ssh连服务器一样直接连上去操作就好了.
查了一下资料,还真可以,且挺简单的,略微记录一下.

准备

PC/Mac/AWS服务器
AWS服务器是免费的,真是太好用且稳定了,现在我已经有两个服务架在上面了,VPN server, 内网穿透服务端,是真香.
另外主要是frp(内网穿透软件)的配置.

步骤

  • 在aws上安装并启动frp服务端: ./frps -c ./frps.ini
  • 在内网Windows上安装并启动客户端: ./frpc.exe -c ./frpc.ini
  • 以上两个详细配置根据需求参照官网操作就OK了.
  • 到这一步就可以ssh连接了: ssh -oPort=[Windows端端口] [windows用户名]@[aws公网IP]
  • 还可以多做两步,将frps和frpc分别在相应的机器上设置为开机启动.参考1参考2
  • 最后, 可以再通过sshpass插件实现ssh密码参数化,然后再将这行命令写成脚本,最终就实现一键登录.

image

哈哈,真香~

后面可以再看看powershell的使用,充分调动起来,跑跑代码,说不定就不用Windows鼠标和键盘了.

相比sklearn 中已有的,可以直接调的评价指标来说,本文提及的指标会复杂一些.
指标的改进是为了针对特定的需求,使模型朝着希望的路径演变,本质上来说是一种加权,针对特定需求朝着特定方向的加权.本文参考的使用案例则是希望能够在分类的时候对身份识别能够有特定的加权,故特改进之.

详参
论文参考
使用案例

只是做一些学习记录,如有遗误,望请指教.

公式

$${score}=w_{0} A U C_{\text {overall}}+\sum_{a=1}^{A} w_{a} M_{p}\left(m_{s, a}\right)$$

最终得分由 整体AUC 与 广义偏差AUC均值 们 加权 得到.
本次涉及到3种偏差AUC(Subgroup_AUC/BPSN_AUC/BNSP_AUC).

整体AUC值是常规操作,详可参sklearn.

其中:

  • $A$表示子指标数量 本次为3
  • $m_{s, a}$表示子组s的第a中偏差指标
  • $w_{a}$ 表示对应的 广义均值 权重, 本次所有权重都为0.25,即等权.
  • $M_{p}\left(m_{s, a}\right)$ 含义

    即广义均值
    本次计算广义偏差AUC均值
    公式为:
    $$
    M_{p}\left(m_{s}\right)=\left(\frac{1}{N} \sum_{s=1}^{N} m_{s}^{p}\right)^{\frac{1}{p}}
    $$
    其中:
    • $M_{p}$表示p级广义均值, 本次取p=-5
    • $m_{s}$表示子组s的偏差指标
    • $N$ 表示子组数量

进一步, 公式的重点是定义了三种偏差AUC.

三种偏差AUC含义

三种偏差AUC的计算公式其实一样,都是计算AUC,不同的是基于不同的数据子集计算.

  • Subgroup_AUC

    基于 满足身份识别的样本所构成的子数据集计算的AUC,这个指标越低表示在特定需求(身份识别)上模型表现越差.

  • BPSN_AUC

    即 Background Positive, Subgroup Negative AUC
    基于提及身份的正面和不提及身份的负面样本所构成的子数据集计算的AUC,这个指标越低表示模型混淆了身份识别,只要提及了身份识别就可能被预测得到更高的值,这不是希望的最佳模型.

  • BNSP_AUC

    即 Background Negative, Subgroup Positive AUC
    基于提及身份的负面和不提及身份的正面样本所构成的子数据集计算的AUC.

结语

所以同理,
将来也可以基于此思路,针对其它的特定需求,设计特定的评价指标.在模型训练的时候就依据需求进行加权.

传统无监督聚类方法一般使用KMEANS及其变类,原理使用距离度量.

背景

希望可以对中文句子进行无监督聚类.
最简单的实现可以是利用word2vec求句子平均向量,然后建立KMEANS模型.
但是,显而易见,这个过程中使用平均使得信息的丢失是比较多的,特别是句子或者文章比较长的情况下,越长信息的丢失也就越多,必然导致模型的可用性下降.

另一种思路是使用NN来对句子\多个句子或者文章这种序列进行特征提取(而不是使用平均)–也就可以展到更高的维度空间去,然后使用使用KMEANS模型.
所以关键就是如何使用NN进行特征提取.

思路

  • 与传统的NLP任务相似,需要有一步补齐操作,如果在多个句子的词场景下,是不是可以在更高一个维度上进行补齐操作后就与传统NLP任务类似了呢?(高了一个维度)
  • 基于word2vec,和补齐\嵌入等操作,直接将高维空间展成二维向量,然后聚类,(这种思路有点将word2vec也视为预训练模型的感觉),也可以再降降维什么的
  • 采用迁移学习的思路,利用其它任务的得到的模型进行中间层输出得到特征

几个思路都可以一试.具体效果可能需要到不同的场景下结合数据进行验证.(对的,是”可能”,不然怎么讲是实验科学呢++)

实操

  • Autoencoder

    使用变分自动编码是一种操作,主要也是利用降维的思路.
    参考:
    Autoencoders
    Sparse autoencoder
    Autoencoders and Word embeddings
    Blog Post Clustering
    Variational Autoencoder base on pytorch

  • 针对NLP的自动编码

    图像领域一般可以用变分自动编码.
    那么sentence级别的是不是可以考虑用LSTM进行自编码呢?
    可谓之LSTM自动编码++
    经过实验表明:是可以的.

  • 针对句子无监督聚类的双路LSTM+Attention自动编码

    经过实验表明,效果很好很好
    我要把它称作: Unsupervised Clustering base on double LSTM&Attention
    思路就是使用上面提到的思路,当然具体过程需要有一些操作.结果表明效果很好,不仅可以捕获到内容,还可以捕获到结构,远远不是平均的效果可以匹敌的.哈哈哈哈,真棒.
    后面可能单独开一篇做一些介绍,先上线再说,哈哈……

效果

句子级别的聚类,特别是多句子(也可以扩展到篇章)的效果很好,当然会比平均复杂一点点,但是效果好太多.

结语

有了一个新的模型架构,
有点引入了无监督对抗的味道,
使用了数据本身做标签,不依赖结果标签,也就实现了无监督,哈哈,我真棒!