从零开发短视频电商 在AWS上用SageMaker部署自定义模型

文章目录

    • 简介
    • 使用model.tar.gz
      • 1.从huggingface上下载模型
      • 2.自定义代码
      • 3.打包为tar 文件
      • 4.上传model.tar.gz到S3
      • 5.部署推理
    • 使用hub
      • 1.在sagemaker上新建个jupyterlab
      • 2.上传官方示例ipynb文件
      • 3.指定HF_MODEL_ID和HF_TASK进行部署和推理
    • inference.py官方示例

简介

  • 原始链接:https://huggingface.co/docs/sagemaker/inference#deploy-with-modeldata
  • https://docs.datarobot.com/en/docs/more-info/how-to/aws/sagemaker/sagemaker-deploy.html
    • 这个可以是java环境或者python环境。

部署的都是从huggingface上的model或者根据huaggingface上的model进行fine-tune后的

一般输入格式如下:

text-classification request body{"inputs": "Camera - You are awarded a SiPix Digital Camera! call 09061221066 fromm landline. Delivery within 28 days."
}
question-answering request body{"inputs": {"question": "What is used for inference?","context": "My Name is Philipp and I live in Nuremberg. This model is used with sagemaker for inference."}
}
zero-shot classification request body{"inputs": "Hi, I recently bought a device from your company but it is not working as advertised and I would like to get reimbursed!","parameters": {"candidate_labels": ["refund","legal","faq"]}
}

所有官方示例

  • https://github.com/huggingface/notebooks/tree/main/sagemaker

推理工具

  • https://github.com/aws/sagemaker-huggingface-inference-toolkit

使用model.tar.gz

1.从huggingface上下载模型

由于模型文件比较大,需要先安装git-lfs

CentOS7安装Git LFS的方法如下:# 安装必要的软件包:
sudo yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel
# 安装Git LFS:
curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.rpm.sh | sudo bash
# 安装
sudo yum install git-lfs
# 配置Git LFS:
git lfs install
# 检测是否安装成功:
git lfs version
如果出现版本信息,说明安装成功。

从huaggingface上clone你想使用的模型,以https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2 为例子

git clone https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2

在这里插入图片描述

2.自定义代码

允许用户覆盖 HuggingFaceHandlerService 的默认方法。您需要创建一个名为 code/ 的文件夹,其中包含 inference.py 文件。

  • HuggingFaceHandlerService

目录结构如下

model.tar.gz/
|- pytorch_model.bin
|- ....
|- code/|- inference.py|- requirements.txt 

inference.py 文件包含自定义推理模块, requirements.txt 文件包含应添加的其他依赖项。自定义模块可以重写以下方法:

  • model_fn(model_dir) 覆盖加载模型的默认方法。返回值 model 将在 predict 中用于预测。 predict 接收参数 model_dir ,即解压后的 model.tar.gz 的路径。
  • transform_fn(model, data, content_type, accept_type) 使用您的自定义实现覆盖默认转换函数。您需要在 transform_fn 中实现您自己的 preprocesspredictpostprocess 步骤。此方法不能与下面提到的 input_fnpredict_fnoutput_fn 组合使用。
  • input_fn(input_data, content_type) 覆盖默认的预处理方法。返回值 data 将在 predict 中用于预测。输入是:
    • input_data 是您请求的原始正文。
    • content_type 是请求标头中的内容类型。
  • predict_fn(processed_data, model) 覆盖默认的预测方法。返回值 predictions 将在 postprocess 中使用。输入是 processed_data ,即 preprocess 的结果。
  • output_fn(prediction, accept) 覆盖后处理的默认方法。返回值 result 将是您请求的响应(例如 JSON )。输入是:
    • predictionspredict 的结果。
    • accept 是 HTTP 请求的返回接受类型,例如 application/json

以下是包含 model_fninput_fnpredict_fnoutput_fn 的自定义推理模块的示例:

from sagemaker_huggingface_inference_toolkit import decoder_encoderdef model_fn(model_dir):# implement custom code to load the modelloaded_model = ...return loaded_model def input_fn(input_data, content_type):# decode the input data  (e.g. JSON string -> dict)data = decoder_encoder.decode(input_data, content_type)return datadef predict_fn(data, model):# call your custom model with the dataoutputs = model(data , ... )return predictionsdef output_fn(prediction, accept):# convert the model output to the desired output format (e.g. dict -> JSON string)response = decoder_encoder.encode(prediction, accept)return response

仅使用 model_fntransform_fn 自定义推理模块:

from sagemaker_huggingface_inference_toolkit import decoder_encoderdef model_fn(model_dir):# implement custom code to load the modelloaded_model = ...return loaded_model def transform_fn(model, input_data, content_type, accept):# decode the input data (e.g. JSON string -> dict)data = decoder_encoder.decode(input_data, content_type)# call your custom model with the dataoutputs = model(data , ... ) # convert the model output to the desired output format (e.g. dict -> JSON string)response = decoder_encoder.encode(output, accept)return response

重点,这里的话我们 all-MiniLM-L6-v2的示例代码如下:

from transformers import AutoTokenizer, AutoModel
import torch
import torch.nn.functional as F#Mean Pooling - Take attention mask into account for correct averaging
def mean_pooling(model_output, attention_mask):token_embeddings = model_output[0] #First element of model_output contains all token embeddingsinput_mask_expanded = attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float()return torch.sum(token_embeddings * input_mask_expanded, 1) / torch.clamp(input_mask_expanded.sum(1), min=1e-9)# Sentences we want sentence embeddings for
sentences = ['This is an example sentence', 'Each sentence is converted']# Load model from HuggingFace Hub
tokenizer = AutoTokenizer.from_pretrained('sentence-transformers/all-MiniLM-L6-v2')
model = AutoModel.from_pretrained('sentence-transformers/all-MiniLM-L6-v2')# Tokenize sentences
encoded_input = tokenizer(sentences, padding=True, truncation=True, return_tensors='pt')# Compute token embeddings
with torch.no_grad():model_output = model(**encoded_input)# Perform pooling
sentence_embeddings = mean_pooling(model_output, encoded_input['attention_mask'])# Normalize embeddings
sentence_embeddings = F.normalize(sentence_embeddings, p=2, dim=1)print("Sentence embeddings:")
print(sentence_embeddings)

我们需要改造下,改为我们自己需要的自定义代码:

from transformers import AutoTokenizer, AutoModel
import torch
import torch.nn.functional as F# 这个方法直接同上
def mean_pooling(model_output, attention_mask):token_embeddings = model_output[0] #First element of model_output contains all token embeddingsinput_mask_expanded = attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float()return torch.sum(token_embeddings * input_mask_expanded, 1) / torch.clamp(input_mask_expanded.sum(1), min=1e-9)# 覆盖 -- 模型加载 参考all-MiniLM-L6-v2给出的示例代码
def model_fn(model_dir):# Load model from HuggingFace Hubtokenizer = AutoTokenizer.from_pretrained(model_dir)model = AutoModel.from_pretrained(model_dir)return model, tokenizer
# 覆盖 -- 预测方法 参考all-MiniLM-L6-v2给出的示例代码
def predict_fn(data, model_and_tokenizer):# destruct model and tokenizermodel, tokenizer = model_and_tokenizer# Tokenize sentencessentences = data.pop("inputs", data)encoded_input = tokenizer(sentences, padding=True, truncation=True, return_tensors='pt')# Compute token embeddingswith torch.no_grad():model_output = model(**encoded_input)# Perform poolingsentence_embeddings = mean_pooling(model_output, encoded_input['attention_mask'])# Normalize embeddingssentence_embeddings = F.normalize(sentence_embeddings, p=2, dim=1)# return dictonary, which will be json serializablereturn {"vectors": sentence_embeddings[0].tolist()}

3.打包为tar 文件

cd all-MiniLM-L6-v2
tar zcvf model.tar.gz *

4.上传model.tar.gz到S3

5.部署推理

这里有好几种方式可选。

第一种:在jupyterlab执行这个脚本,替换model等参数即可。

  • https://github.com/huggingface/notebooks/blob/main/sagemaker/10_deploy_model_from_s3/deploy_transformer_model_from_s3.ipynb

第二种:这个是吧上面所有步骤都包含了,但是这种无法处理我们在私有环境fine-tune后的模型。

  • https://github.com/huggingface/notebooks/blob/main/sagemaker/17_custom_inference_script/sagemaker-notebook.ipynb

第三种:可视化部署,我重点介绍下这个吧

入口如下:

注意下面的选项

  • 容器框架根据实际情况选择,这里我们就选择如图
  • S3 URI
  • IAM role:
    • 可以去IAM创建角色
      • AmazonS3FullAccess
      • AmazonSageMakerFullAccess
    • 也可以去JumpStart中的model去复制过来。

使用hub

原文:https://huggingface.co/docs/sagemaker/inference#deploy-a-model-from-the–hub

这种方式没有上面的方式灵活度高,支持的model也没有上面的方式多。

1.在sagemaker上新建个jupyterlab

2.上传官方示例ipynb文件

  • https://github.com/huggingface/notebooks/blob/main/sagemaker/11_deploy_model_from_hf_hub/deploy_transformer_model_from_hf_hub.ipynb

3.指定HF_MODEL_ID和HF_TASK进行部署和推理

inference.py官方示例

  • https://sagemaker-examples.readthedocs.io/en/latest/sagemaker-script-mode/pytorch_bert/deploy_bert_outputs.html#Write-the-Inference-Script
import os
import json
from transformers import BertTokenizer, BertModeldef model_fn(model_dir):"""Load the model for inference"""model_path = os.path.join(model_dir, 'model/')# Load BERT tokenizer from disk.tokenizer = BertTokenizer.from_pretrained(model_path)# Load BERT model from disk.model = BertModel.from_pretrained(model_path)model_dict = {'model': model, 'tokenizer':tokenizer}return model_dictdef predict_fn(input_data, model):"""Apply model to the incoming request"""tokenizer = model['tokenizer']bert_model = model['model']encoded_input = tokenizer(input_data, return_tensors='pt')return bert_model(**encoded_input)def input_fn(request_body, request_content_type):"""Deserialize and prepare the prediction input"""if request_content_type == "application/json":request = json.loads(request_body)else:request = request_bodyreturn requestdef output_fn(prediction, response_content_type):"""Serialize and prepare the prediction output"""if response_content_type == "application/json":response = str(prediction)else:response = str(prediction)return response

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/223053.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【QT表格-6】QTableWidget的currentCellChanged实现中途撤销

背景: 【QT表格-1】QStandardItem的堆内存释放需要单独delete,还是随QStandardItemModel的remove或clear自动销毁?-CSDN博客 【QT表格-2】QTableWidget单元格结束编辑操作endEditting_qtablewidget 单元格编辑事件-CSDN博客 【QT表格-3】Q…

了解树和学习二叉树

1.树 1.1 概念 树是一种 非线性 的数据结构,它是由 n ( n>0 )个有限结点组成一个具有层次关系的集合。 把它叫做树是因为它看 起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的 。 注意:树形结构中…

使用 uiautomatorviewer 获取元素的定位信息

1. 使用 adb 连接设备(真机或模拟器) 连接夜神模拟器:adb connect 127.0.0.1:62001 连接MuMu模拟器:adb connect 127.0.0.1:7555 2. 打开 uiautomatorviewer 在 android-sdk --> tools 目录,找到 uiautomatorvie…

momentum2靶机

文章妙语 遇事不决,可问春风; 春风不语,遵循己心。 文章目录 文章妙语前言一、信息收集1.IP地址扫描2.端口扫描3.目录扫描 二,漏洞发现分析代码bp爆破1.生成字典2.生成恶意shell.php2.抓包 三,漏洞利用1.反弹shell 四…

第一次记录QPSK,BSPK,MPSK,QAM—MATLAB实现

最近有偶然的机会学习了一次QPSK防止以后忘记又得找资料,这里就详细的记录一下 基于 QPSK 的通信系统如图 1 所示,QPSK 调制是目前最常用的一种卫星数字和数 字集群信号调制方式,它具有较高的频谱利用率、较强的抗干扰性、在电路上实现也较为…

使用阿里云性能测试工具 JMeter 场景压测 RocketMQ 最佳实践

作者:森元 需求背景 新业务上线前,我们通常需要对系统的不同中间件进行压测,找到当前配置下中间件承受流量的上限,从而确定上游链路的限流规则,保护系统不因突发流量而崩溃。阿里云 PTS 的 JMeter 压测可以支持用户上…

用户管理第2节课-idea 2023.2 后端一删除表,从零开始---【本人】

一、清空model文件夹下,所有文件 1.1.1效果如下: 1.1代码内容 package com.daisy.usercenter.model;import lombok.Data;Data public class User {private Long id;private String name;private Integer age;private String email; }二、清空mapper文件…

单调栈分类、封装和总结

作者推荐 map|动态规划|单调栈|LeetCode975:奇偶跳 通过枚举最小(最大)值不重复、不遗漏枚举所有子数组 C算法:美丽塔O(n)解法单调栈左右寻找第一个小于maxHeight[i]的left,right,[left,right]直接的高度都是maxHeight[i] 可以…

[kubernetes]控制平面ETCD

什么是ETCD CoreOS基于Raft开发的分布式key-value存储,可用于服务发现、共享配置以及一致性保障(如数据库选主、分布式锁等)etcd像是专门为集群环境的服务发现和注册而设计,它提供了数据TTL失效、数据改变监视、多值、目录监听、…

docker安装ES:7.8和Kibana:7.8

本文适用于centos7,快速入手练习es语法 前置:安装docker教程docker、docker-component安装-CSDN博客 1.安装es 9200为启动端口,9300为集群端口 docker pull elasticsearch:7.8.0mkdir -p /mydata/elasticsearch/pluginsmkdir -p /mydata/elasticsear…

debian10安装配置vim+gtags

sudo apt install global gtags --version gtags //生成gtag gtags-cscope //查看gtags gtags与leaderf配合使用 参考: 【VIM】【LeaderF】【Gtags】打造全定制化的IDE开发环境! - 知乎

Vue CLI 设置 publicPath:打包后的应用可部署在任意路径

前言 领导要重新部署多个应用环境,且不受路径层级影响。 于是找到了 Vue CLI 配置 publicpath 配置说明 下图所示: / :默认值,应用部署在根路径上;./:注意前面加了一个点,应用可部署在任意路…

【Earth Engine】协同Sentinel-1/2使用随机森林回归实现高分辨率相对财富(贫困)制图

目录 1 简介与摘要2 思路3 效果预览4 代码思路5 完整代码6 后记 1 简介与摘要 最近在做一些课题,需要使用Sentinel-1/2进行机器学习制图。 然后想着总结一下相关数据和方法,就花半小时写了个代码。 然后再花半小时写下这篇博客记录一下。 因为基于多次拍…

【Python小游戏】某程序员自制《苹果大赛》,赶紧来抢~“免费的平安夜苹果,你说是不是最甜的鸭?”(附源码)

导语 很久不见,我是木木子鸭~2023发生了太多事情啦,我将重新启航,开启新的一页。 希望不管是文章还是各种小程序都能够帮到大家,大家也要继续支持我哦~我将继续努力更新! ——祝你祝我 在这个冬天—— 爱与好运同在 …

车云TCP链路偶现链接失联问题排查

一、问题分析 1.1 车云tcp长连接分析排查 在15:37:32.039上线, 在 16:07:26.527下线,车云长连接通道稳定,且该期间心跳数据正常。 1.2 云向驾仓推送数据分析 在15:37:42 进行车辆接管后,该车辆下线,且无法在上线&am…

AtomHub 开源容器镜像中心开放公测,国内服务稳定下载

由开放原子开源基金会主导,华为、浪潮、DaoCloud、谐云、青云、飓风引擎以及 OpenSDV 开源联盟、openEuler 社区、OpenCloudOS 社区等成员单位共同发起建设的 AtomHub 可信镜像中心正式开放公测。AtomHub 秉承共建、共治、共享的理念,旨在为开源组织和开…

Java中使用JTS实现WKB数据写入、转换字符串、读取

场景 Java中使用JTS实现WKT字符串读取转换线、查找LineString的list中距离最近的线、LineString做缓冲区扩展并计算点在缓冲区内的方位角: Java中使用JTS实现WKT字符串读取转换线、查找LineString的list中距离最近的线、LineString做缓冲区扩展并计算点在缓冲区内…

户用光伏设计有哪些特点?

随着科技的发展和人们对可再生能源的追求,户用光伏设计已经逐渐成为一种新型的能源解决方案。它不仅有助于降低能源成本,而且对环境保护有着积极的影响。那么,户用光伏设计究竟有哪些特点呢? 首先,户用光伏设计的核心在…

c++动态内存与智能指针

前言 静态内存:用于保存局部静态变量、类内的静态数据成员以及全局变量栈:用于保存函数内部的非static变量堆:存储动态分配的对象(程序运行时分配的对象) 静态内存和栈内存的对象由编译器自动创建和销毁 而堆区的动态…

分布式搜索elasticsearch概念

什么是elasticsearch? elasticsearch是一款非常强大的开源搜索引擎,可以帮助我们从海量数据中快速找到需要的内容 目录 elasticsearch的场景 elasticsearch的发展 Lucene篇 Elasticsearch篇 elasticsearch的安装 elasticsearch的场景 elasticsear…