一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

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

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

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

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

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

掃碼添加小助手

加入工程師交流群

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

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

  • PyTorch-YOLOv3模型的Web頁(yè)面展示程序的編寫
  • 模型的服務(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)程尚待考證),而中文博客里面能查到的資料基本都在說(shuō)Flask默認(rèn)單進(jìn)程單線程。

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

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

1. 制作模型演示界面

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

上傳頁(yè)面和展示頁(yè)面

做識(shí)別演示需要用到兩個(gè)html頁(yè)面,代碼也比較簡(jiǎn)單,編寫如下:

上傳界面







使用Flask上傳本地圖片

展示界面






使用Flask上傳本地圖片

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

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

flask上傳圖片及展示功能

然后就可以編寫flask代碼了,為了更好地展示圖片,可以向html頁(yè)面?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)文件緩存過(guò)期時(shí)間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":"請(qǐng)檢查上傳的圖片類型,僅限于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)檢測(cè)函數(shù)

原項(xiàng)目中提供了detection.py來(lái)做批量的圖片檢測(cè),需要稍微修改一下才能用來(lái)做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)

展示效果

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

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

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

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

flask服務(wù)接口

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

gunicorn啟動(dòng)多個(gè)實(shí)例

新版的flask已經(jīng)支持多進(jìn)程了,不過(guò)用在生產(chǎn)環(huán)境還是不太穩(wěn)定,一般生產(chǎn)環(huán)境會(huì)使用gunicorn來(lái)啟動(dòng)多個(gè)服務(wù)。
使用如下命令即可啟動(dòng)多個(gè)圖像分類實(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ù)雜,也可以將配置寫入一個(gè)文件中,如:

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

然后運(yùn)行:

gunicorn -c gunicorn.conf sim_server:app

nginx負(fù)載均衡

如果有多個(gè)服務(wù)器,可以使用nginx做請(qǐng)求分發(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        }    }}

然后按配置文件啟動(dòng)

sudo nginx -c nginx.conf

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

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

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

然后使用下面的方式訪問(wèn)
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ù)干貨請(qǐng)關(guān)注嵌入式AI專欄。

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

    關(guān)注

    73

    文章

    5560

    瀏覽量

    122750
  • pytorch
    +關(guān)注

    關(guān)注

    2

    文章

    809

    瀏覽量

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

掃碼添加小助手

加入工程師交流群

    評(píng)論

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

    如何使用Docker部署模型

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

    如何在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 ?481次閱讀

    K230D部署模型失敗的原因?

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

    【ELF 2學(xué)習(xí)板試用】ELF2開發(fā)板(飛凌嵌入式)搭建深度學(xué)習(xí)環(huán)境部署(RKNN環(huán)境部署

    模型進(jìn)行量化部署轉(zhuǎn)換為rknn模型,并編譯好基本腳本上傳至開發(fā)板。 模型工具的介紹 RKNN-Toolkit2 ? ?RKNN-Toolkit2 是由瑞芯微電子開發(fā)的一套
    發(fā)表于 02-04 14:15

    Flexus X 實(shí)例 ultralytics 模型 yolov10 深度學(xué)習(xí) AI 部署與應(yīng)用

    模型迭代,讓 AI 智能觸手可及。把握此刻,讓創(chuàng)新不再受限! ???本實(shí)驗(yàn)演示從 0 到 1 部署 YOLOv10 深度學(xué)習(xí) AI 大模型
    的頭像 發(fā)表于 12-24 12:24 ?778次閱讀
    Flexus X 實(shí)例 ultralytics <b class='flag-5'>模型</b> yolov10 <b class='flag-5'>深度</b><b class='flag-5'>學(xué)習(xí)</b> AI <b class='flag-5'>部署</b>與應(yīng)用

    AI模型部署邊緣設(shè)備的奇妙之旅:目標(biāo)檢測(cè)模型

    以及邊緣計(jì)算能力的增強(qiáng),越來(lái)越多的目標(biāo)檢測(cè)應(yīng)用開始直接在靠近數(shù)據(jù)源的邊緣設(shè)備上運(yùn)行。這不僅減少了數(shù)據(jù)傳輸延遲,保護(hù)了用戶隱私,同時(shí)也減輕了云端服務(wù)器的壓力。然而,在邊緣部署高效且準(zhǔn)確的目標(biāo)檢測(cè)
    發(fā)表于 12-19 14:33

    AI模型部署邊緣設(shè)備的奇妙之旅:如何實(shí)現(xiàn)手寫數(shù)字識(shí)別

    新的數(shù)據(jù)樣本,另一個(gè)是判別器用來(lái)判斷這些樣本的真實(shí)性。兩者相互競(jìng)爭(zhēng),共同進(jìn)化,最終實(shí)現(xiàn)高質(zhì)量的數(shù)據(jù)合成。 2.4 模型優(yōu)化技術(shù) 在將深度學(xué)習(xí)模型部署
    發(fā)表于 12-06 17:20

    Pytorch深度學(xué)習(xí)訓(xùn)練的方法

    掌握這 17 種方法,用最省力的方式,加速你的 Pytorch 深度學(xué)習(xí)訓(xùn)練。
    的頭像 發(fā)表于 10-28 14:05 ?643次閱讀
    <b class='flag-5'>Pytorch</b><b class='flag-5'>深度</b><b class='flag-5'>學(xué)習(xí)</b>訓(xùn)練的方法

    使用OpenVINO C++在哪吒開發(fā)板上推理Transformer模型

    OpenVINO 是一個(gè)開源工具套件,用于對(duì)深度學(xué)習(xí)模型進(jìn)行優(yōu)化并在云端、邊緣進(jìn)行部署。它能在諸如生成式人工智能、視頻、音頻以及語(yǔ)言等各類應(yīng)用場(chǎng)景中加快
    的頭像 發(fā)表于 10-12 09:55 ?977次閱讀
    使用OpenVINO C++在哪吒開發(fā)板上推理Transformer<b class='flag-5'>模型</b>

    新手小白怎么通過(guò)云服務(wù)器跑pytorch

    安裝PyTorch的步驟可以根據(jù)不同的操作系統(tǒng)和需求有所差異,通過(guò)云服務(wù)器運(yùn)行PyTorch的過(guò)程主要包括選擇GPU云服務(wù)器平臺(tái)、配置服務(wù)
    的頭像 發(fā)表于 09-25 11:35 ?557次閱讀

    基于Pytorch訓(xùn)練并部署ONNX模型在TDA4應(yīng)用筆記

    電子發(fā)燒友網(wǎng)站提供《基于Pytorch訓(xùn)練并部署ONNX模型在TDA4應(yīng)用筆記.pdf》資料免費(fèi)下載
    發(fā)表于 09-11 09:24 ?0次下載
    基于<b class='flag-5'>Pytorch</b>訓(xùn)練并<b class='flag-5'>部署</b>ONNX<b class='flag-5'>模型</b>在TDA4應(yīng)用筆記

    PyTorch深度學(xué)習(xí)開發(fā)環(huán)境搭建指南

    PyTorch作為一種流行的深度學(xué)習(xí)框架,其開發(fā)環(huán)境的搭建對(duì)于深度學(xué)習(xí)研究者和開發(fā)者來(lái)說(shuō)至關(guān)重要。在Windows操作系統(tǒng)上搭建
    的頭像 發(fā)表于 07-16 18:29 ?2465次閱讀

    深度學(xué)習(xí)模型量化方法

    深度學(xué)習(xí)模型量化是一種重要的模型輕量化技術(shù),旨在通過(guò)減少網(wǎng)絡(luò)參數(shù)的比特寬度來(lái)減小模型大小和加速推理過(guò)程,同時(shí)盡量保持
    的頭像 發(fā)表于 07-15 11:01 ?1091次閱讀
    <b class='flag-5'>深度</b><b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>模型</b>量化方法

    深度學(xué)習(xí)算法在嵌入式平臺(tái)上的部署

    隨著人工智能技術(shù)的飛速發(fā)展,深度學(xué)習(xí)算法在各個(gè)領(lǐng)域的應(yīng)用日益廣泛。然而,將深度學(xué)習(xí)算法部署到資源受限的嵌入式平臺(tái)上,仍然是一個(gè)具有挑戰(zhàn)性的任
    的頭像 發(fā)表于 07-15 10:03 ?3134次閱讀

    pytorch中有神經(jīng)網(wǎng)絡(luò)模型

    當(dāng)然,PyTorch是一個(gè)廣泛使用的深度學(xué)習(xí)框架,它提供了許多預(yù)訓(xùn)練的神經(jīng)網(wǎng)絡(luò)模型。 PyTorch中的神經(jīng)網(wǎng)絡(luò)
    的頭像 發(fā)表于 07-11 09:59 ?1789次閱讀