91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

深度學(xué)習(xí)應(yīng)用的服務(wù)端部署—PyTorch模型部署

電子設(shè)計(jì) ? 來源:電子設(shè)計(jì) ? 作者:電子設(shè)計(jì) ? 2020-12-08 22:29 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

文章轉(zhuǎn)載于微信公眾號:GiantPandaCV
作者: 阿呆

【GiantPandaCV導(dǎo)讀】這篇文章包含與PyTorch模型部署相關(guān)的兩部分內(nèi)容:

  • PyTorch-YOLOv3模型的Web頁面展示程序的編寫
  • 模型的服務(wù)接口相關(guān)工具的使用

0. 環(huán)境依賴:

系統(tǒng):Ubuntu 18.04
Python版本:3.7
依賴Python包:1. PyTorch==1.3 2. Flask==0.12 3. Gunicorn

需要注意的是Flask 0.12中默認(rèn)的單進(jìn)程單線程,而最新的1.0.2則不是(具體是多線程還是多進(jìn)程尚待考證),而中文博客里面能查到的資料基本都在說Flask默認(rèn)單進(jìn)程單線程。

依賴工具 1. nginx 2. apache2-utils

nginx 用于代理轉(zhuǎn)發(fā)和負(fù)載均衡,apache2-utils用于測試接口

1. 制作模型演示界面

圖像識別任務(wù)的展示這項(xiàng)工程一般是面向客戶的,這種場景下不可能把客戶拉到你的電腦前面,敲一行命令,等matplotlib彈個結(jié)果窗口出來??倸w還是要有個圖形化界面才顯得有點(diǎn)誠意。
為了節(jié)約時間,我們選擇了Flask框架來開發(fā)這個界面。

上傳頁面和展示頁面

做識別演示需要用到兩個html頁面,代碼也比較簡單,編寫如下:

上傳界面







使用Flask上傳本地圖片

展示界面






使用Flask上傳本地圖片

{{?url_for('static',?filename=?path,_t=val1)?}}

上傳界面如下圖所示,覺得丑的話可以找前端同事美化一下:

flask上傳圖片及展示功能

然后就可以編寫flask代碼了,為了更好地展示圖片,可以向html頁面?zhèn)魅雸D片地址參數(shù)。

fromflaskimportFlask,render_template,request,redirect,url_for,make_response,jsonifyfromwerkzeug.utilsimportsecure_filenameimportosimportcv2importtimefromdatetimeimporttimedeltafrommainimportrun,confALLOWED_EXTENSIONS=set(["png","jpg","JPG","PNG","bmp"])defis_allowed_file(filename):return'.'infilenameandfilename.rsplit('.',1)[1]inALLOWED_EXTENSIONSapp=Flask(__name__)#靜態(tài)文件緩存過期時間app.send_file_max_age_default=timedelta(seconds=1)@app.route("/upload",methods=['POST','GET'])defupload():ifrequest.method=="POST":f=request.files['file']ifnot(fandis_allowed_file(f.filename)):returnjsonify({"error":1001,"msg":"請檢查上傳的圖片類型,僅限于png、PNG、jpg、JPG、bmp"})user_input=request.form.get("name")basepath=os.path.dirname(__file__)upload_path=os.path.join(basepath,"static/images",secure_filename(f.filename))f.save(upload_path)detected_path=os.path.join(basepath,"static/images","output"+secure_filename(f.filename))run(upload_path,conf,detected_path)#returnrender_template("upload_ok.html",userinput=user_input,val1=time.time(),path=detected_path)path="/images/"+"output"+secure_filename(f.filename)returnrender_template("upload_ok.html",path=path,val1=time.time())returnrender_template("upload.html")if__name__=="__main__":app.run(host='0.0.0.0',port=8888,debug=True)

目標(biāo)檢測函數(shù)

原項(xiàng)目中提供了detection.py來做批量的圖片檢測,需要稍微修改一下才能用來做flask代碼中的接口。

from__future__importdivisionfrommodelsimport*fromutils.utilsimport*fromutils.datasetsimport*importosimportsysimporttimeimportdatetimeimportargparsefromPILimportImageimporttorchfromtorchvisionimportdatasetsfromtorch.autogradimportVariableimportmatplotlib.pyplotaspltimportmatplotlib.patchesaspatchesfrommatplotlib.tickerimportNullLocatorclasscustom_dict(dict):def__init__(self,d=None):ifdisnotNone:fork,vind.items():self[k]=vreturnsuper().__init__()def__key(self,key):return""ifkeyisNoneelsekey.lower()def__str__(self):importjsonreturnjson.dumps(self)def__setattr__(self,key,value):self[self.__key(key)]=valuedef__getattr__(self,key):returnself.get(self.__key(key))def__getitem__(self,key):returnsuper().get(self.__key(key))def__setitem__(self,key,value):returnsuper().__setitem__(self.__key(key),value)conf=custom_dict({"model_def":"config/yolov3.cfg","weights_path":"weights/yolov3.weights","class_path":"data/coco.names","conf_thres":0.8,"nms_thres":0.4,"img_size":416})defrun(img_path,conf,target_path):device=torch.device("cuda"iftorch.cuda.is_available()else"cpu")os.makedirs("output",exist_ok=True)classes=load_classes(conf.class_path)model=Darknet(conf.model_def,img_size=conf.img_size).to(device)ifconf.weights_path.endswith(".weights"):#Loaddarknetweightsmodel.load_darknet_weights(conf.weights_path)else:#Loadcheckpointweightsmodel.load_state_dict(torch.load(conf.weights_path))model.eval()img=Image.open(img_path).convert("RGB")img=img.resize(((img.size[0]//32)*32,(img.size[1]//32)*32))img_array=np.array(img)img_tensor=pad_to_square(transforms.ToTensor()(img),0)[0].unsqueeze(0)conf.img_size=img_tensor.shape[2]withtorch.no_grad():detections=model(img_tensor)detections=non_max_suppression(detections,conf.conf_thres,conf.nms_thres)[0]cmap=plt.get_cmap("tab20b")colors=[cmap(i)foriinnp.linspace(0,1,20)]plt.figure()fig,ax=plt.subplots(1)ax.imshow(img_array)ifdetectionsisnotNone:#Rescaleboxestooriginalimagedetections=rescale_boxes(detections,conf.img_size,img_array.shape[:2])unique_labels=detections[:,-1].cpu().unique()n_cls_preds=len(unique_labels)bbox_colors=random.sample(colors,n_cls_preds)forx1,y1,x2,y2,conf,cls_conf,cls_predindetections:print("/t+Label:%s,Conf:%.5f"%(classes[int(cls_pred)],cls_conf.item()))box_w=x2-x1box_h=y2-y1color=bbox_colors[int(np.where(unique_labels==int(cls_pred))[0])]#CreateaRectanglepatchbbox=patches.Rectangle((x1,y1),box_w,box_h,linewidth=2,edgecolor=color,facecolo)#Addthebboxtotheplotax.add_patch(bbox)#Addlabelplt.text(x1,y1,s=classes[int(cls_pred)],colo,verticalalignmen,bbox={"color":color,"pad":0},)#Savegeneratedimagewithdetectionsplt.axis("off")plt.gca().xaxis.set_major_locator(NullLocator())plt.gca().yaxis.set_major_locator(NullLocator())filename=img_path.split("/")[-1].split(".")[0]plt.savefig(target_path,bbox_inches='tight',pad_inches=0.0)plt.close()if__name__=="__main__":run("data/samples/dog.jpg",conf)

展示效果

編寫好了之后,啟動server.py,在本地打開localhost:8888/upload就可以看到如下界面了,把圖片上傳上去,很快就能得到檢測結(jié)果。
結(jié)果如下圖所示:

2. 深度學(xué)習(xí)的服務(wù)接口編寫

接下來介紹的是在生產(chǎn)環(huán)境下的部署,使用的是flask+gunicorn+nginx的方式,可以處理較大規(guī)模的請求。
下面以圖像分類模型為例演示一下深度學(xué)習(xí)服務(wù)接口如何編寫。

對于深度學(xué)習(xí)工程師來說,學(xué)習(xí)這些內(nèi)容主要是了解一下自己的模型在生產(chǎn)環(huán)境的運(yùn)行方式,便于在服務(wù)出現(xiàn)問題的時候與開發(fā)的同事一起進(jìn)行調(diào)試。

flask服務(wù)接口

接口不需要有界面顯示,當(dāng)然也可以添加一個API介紹界面,方便調(diào)用者查看服務(wù)是否已經(jīng)啟動。

fromflaskimportFlask,requestfromwerkzeug.utilsimportsecure_filenameimportuuidfromPILimportImageimportosimporttimeimportbase64importjsonimporttorchfromtorchvision.modelsimportresnet18fromtorchvision.transformsimportToTensorfromkeysimportkeyapp=Flask(__name__)net=resnet18(pretrained=True)net.eval()@app.route("/",methods=["GET"])defshow():return"classifierapi"@app.route("/run",methods=["GET","POST"])defrun():file=request.files['file']base_path=os.path.dirname(__file__)ifnotos.path.exists(os.path.join(base_path,"temp")):os.makedirs(os.path.join(base_path,"temp"))file_name=uuid.uuid4().hexupload_path=os.path.join(base_path,"temp",file_name)file.save(upload_path)img=Image.open(upload_path)img_tensor=ToTensor()(img).unsqueeze(0)out=net(img_tensor)pred=torch.argmax(out,dim=1)return"result:{}".format(key[pred])if__name__=="__main__":app.run(hos,port=5555,debug=True)

在命令行輸入python server.py即可啟動服務(wù)。

gunicorn啟動多個實(shí)例

新版的flask已經(jīng)支持多進(jìn)程了,不過用在生產(chǎn)環(huán)境還是不太穩(wěn)定,一般生產(chǎn)環(huán)境會使用gunicorn來啟動多個服務(wù)。
使用如下命令即可啟動多個圖像分類實(shí)例

gunicorn -w 4 -b 0.0.0.0:5555 server:app

輸出如下內(nèi)容代表服務(wù)創(chuàng)建成功:

[2020-02-11 14:50:24 +0800] [892] [INFO] Starting gunicorn 20.0.4[2020-02-11 14:50:24 +0800] [892] [INFO] Listening at: http://0.0.0.0:5555 (892)[2020-02-11 14:50:24 +0800] [892] [INFO] Using worker: sync[2020-02-11 14:50:24 +0800] [895] [INFO] Booting worker with pid: 895[2020-02-11 14:50:24 +0800] [896] [INFO] Booting worker with pid: 896[2020-02-11 14:50:24 +0800] [898] [INFO] Booting worker with pid: 898[2020-02-11 14:50:24 +0800] [899] [INFO] Booting worker with pid: 899

如果配置比較復(fù)雜,也可以將配置寫入一個文件中,如:

bind='0.0.0.0:5555'timeout=10workers=4

然后運(yùn)行:

gunicorn -c gunicorn.conf sim_server:app

nginx負(fù)載均衡

如果有多個服務(wù)器,可以使用nginx做請求分發(fā)與負(fù)載均衡。
安裝好nginx之后,修改nginx的配置文件

worker_processes auto;error_log /var/log/nginx/error.log;pid /run/nginx.pid;# Load dynamic modules. See /usr/share/nginx/README.dynamic.include /usr/share/nginx/modules/*.conf;events {    worker_connections 1024;}http {    server    {        listen 5556; # nginx端口        server_name localhost;        location / {            proxy_pass http://localhost:5555/run; # gunicorn的url        }    }}

然后按配置文件啟動

sudo nginx -c nginx.conf

測試一下服務(wù)是否正常

啟動了這么多服務(wù)之后,可以使用apache2-utils來測試服務(wù)的并發(fā)性能。
使用apache2-utils進(jìn)行上傳圖片的post請求方法參考:
https://gist.github.com/chill...

嚴(yán)格參照,注意一個標(biāo)點(diǎn),一個符號都不要錯。使用這種方法傳輸圖片的base64編碼,在服務(wù)端不需要解碼也能使用

然后使用下面的方式訪問
gunicorn 接口

ab -n 2 -c 2 -T "multipart/form-data; boundary=1234567890" -p turtle.txt http://localhost:5555/run

nginx 接口

ab -n 2 -c 2 -T "multipart/form-data; boundary=1234567890" -p turtle.txt http://localhost:5556/run

- END -

推薦閱讀

更多嵌入式AI技術(shù)干貨請關(guān)注嵌入式AI專欄。

審核編輯:符乾江
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 深度學(xué)習(xí)
    +關(guān)注

    關(guān)注

    73

    文章

    5599

    瀏覽量

    124398
  • pytorch
    +關(guān)注

    關(guān)注

    2

    文章

    813

    瀏覽量

    14853
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點(diǎn)推薦

    AI側(cè)部署開發(fā)(SC171開發(fā)套件V2-FAS)

    AI側(cè)部署開發(fā)(SC171開發(fā)套件V2-FAS) 序列 課程名稱 視頻課程時長 視頻課程鏈接 課件鏈接 工程源碼 1 Fibo AI Stack模型轉(zhuǎn)化指南 27分19秒 https
    發(fā)表于 02-11 11:44

    OPC UA 服務(wù)端用戶認(rèn)證的底層邏輯:哈希與加鹽應(yīng)用詳解

    摘要在基于UnifiedAutomationSDK開發(fā)OPCUA服務(wù)端時,用戶認(rèn)證(UserAuthentication)是安全體系的第一道防線。除了傳輸層的加密通道外,服務(wù)端如何安全地存儲和驗(yàn)證
    的頭像 發(fā)表于 01-15 17:29 ?152次閱讀
    OPC UA <b class='flag-5'>服務(wù)端</b>用戶認(rèn)證的底層邏輯:哈希與加鹽應(yīng)用詳解

    AI側(cè)部署開發(fā)(SC171開發(fā)套件V3)2026版

    AI側(cè)部署開發(fā)(SC171開發(fā)套件V3)2026版 序列 課程名稱 視頻課程時長 視頻課程鏈接 課件鏈接 工程源碼 1 Fibo AI Stack模型轉(zhuǎn)化指南 27分19秒 https
    發(fā)表于 01-15 10:31

    【團(tuán)購】獨(dú)家全套珍藏!龍哥LabVIEW視覺深度學(xué)習(xí)實(shí)戰(zhàn)課(11大系列課程,共5000+分鐘)

    (第10系列)、YOLOv8-Tiny工業(yè)優(yōu)化版(第9系列),滿足產(chǎn)線設(shè)備算力限制,模型推理速度提升300%。 LabVIEW生態(tài)整合 作為工業(yè)自動化領(lǐng)域主流開發(fā)環(huán)境,LabVIEW與深度學(xué)
    發(fā)表于 12-04 09:28

    【團(tuán)購】獨(dú)家全套珍藏!龍哥LabVIEW視覺深度學(xué)習(xí)實(shí)戰(zhàn)課程(11大系列課程,共5000+分鐘)

    (第10系列)、YOLOv8-Tiny工業(yè)優(yōu)化版(第9系列),滿足產(chǎn)線設(shè)備算力限制,模型推理速度提升300%。 LabVIEW生態(tài)整合 作為工業(yè)自動化領(lǐng)域主流開發(fā)環(huán)境,LabVIEW與深度學(xué)
    發(fā)表于 12-03 13:50

    DeepSeek模型如何在云服務(wù)器上部署?

    隨著大型語言模型(LLM)的應(yīng)用日益普及,許多開發(fā)者和企業(yè)希望將像DeepSeek這樣的優(yōu)秀模型部署到自己的云服務(wù)器上,以實(shí)現(xiàn)私有化、定制化服務(wù)
    的頭像 發(fā)表于 10-13 16:52 ?946次閱讀

    vision board部署模型到openmv的代碼導(dǎo)致連接超時怎么解決?

    在env終端中勾選了tiflte support后燒錄mdk到板子上后就開始顯示連接不到 無法部署模型
    發(fā)表于 09-19 07:59

    Arm方案 基于Arm架構(gòu)的邊緣側(cè)設(shè)備(樹莓派或 NVIDIA Jetson Nano)上部署PyTorch模型

    本文將為你展示如何在樹莓派或 NVIDIA Jetson Nano 等基于 Arm 架構(gòu)的邊緣側(cè)設(shè)備上部署 PyTorch 模型。
    的頭像 發(fā)表于 07-28 11:50 ?2877次閱讀

    【Banana Pi BPI-RV2開發(fā)板試用體驗(yàn)】部署內(nèi)網(wǎng)穿透

    的,所以要下載riscv64的版本。 部署 解壓下載的壓縮包,分別部署 frpc 客戶和 frps 服務(wù)器。 $ ls -l total 31004 -rw-r--r-- 1 xxx
    發(fā)表于 06-29 20:05

    企業(yè)部署AI大模型怎么做

    當(dāng)下,AI大模型已成為驅(qū)動決策自動化、服務(wù)智能化與產(chǎn)品創(chuàng)新的核心引擎。然而,企業(yè)面對動輒數(shù)百億參數(shù)的大模型部署時,常陷入算力不足、響應(yīng)延遲高、成本失控等困境。如何突破瓶頸,實(shí)現(xiàn)高效、穩(wěn)
    的頭像 發(fā)表于 06-04 09:26 ?888次閱讀

    如何使用Docker部署模型

    隨著深度學(xué)習(xí)和大模型的快速發(fā)展,如何高效地部署這些模型成為了一個重要的挑戰(zhàn)。Docker 作為一種輕量級的容器化技術(shù),能夠?qū)?/div>
    的頭像 發(fā)表于 05-24 16:39 ?1118次閱讀

    HarmonyOS5云服務(wù)技術(shù)分享--Serverless抽獎模板部署

    測試服務(wù)PTS 希望這篇教程能幫你快速上手!如果部署過程中遇到問題,歡迎在評論區(qū)留言交流~ 也歡迎關(guān)注我的技術(shù)博客,每周更新HarmonyOS開發(fā)實(shí)戰(zhàn)技巧。祝各位開發(fā)者一次部署成功,活動火爆上線! ?
    發(fā)表于 05-22 20:25

    如何在RAKsmart服務(wù)器上實(shí)現(xiàn)企業(yè)AI模型部署

    AI模型的訓(xùn)練與部署需要強(qiáng)大的算力支持、穩(wěn)定的網(wǎng)絡(luò)環(huán)境和專業(yè)的技術(shù)管理。RAKsmart作為全球領(lǐng)先的服務(wù)器托管與云計(jì)算服務(wù)提供商,已成為企業(yè)部署
    的頭像 發(fā)表于 03-27 09:46 ?939次閱讀

    【幸狐Omni3576邊緣計(jì)算套件試用體驗(yàn)】DeepSeek 部署及測試

    、RKLLM 庫、編譯和運(yùn)行、效果演示等。 簡介 介紹了板部署的 DeepSeek 模型及其部署方案。 DeepSeek DeepSeek 是由杭州
    發(fā)表于 03-21 19:31

    K230D部署模型失敗的原因?

    MicroPython部署的無法正常運(yùn)行,采用C++版本的無法實(shí)現(xiàn)部署 嘗試解決過程 1.考慮到可能是固件不匹配的問題,重新燒錄了流程(生成模型后給的readme)中要求的固件,依舊無法成功
    發(fā)表于 03-11 06:19