在Windows上部署PyTorch模型的三種主流方法
摘要:本文介紹了在Windows系統(tǒng)上部署PyTorch模型的三種主流方法。方案一通過(guò)TorchScript實(shí)現(xiàn)高性能推理,支持Python和C++調(diào)用;方案二使用FastAPI構(gòu)建Web API服務(wù),適合后端調(diào)用;方案三通過(guò)PyInstaller打包為桌面exe程序,便于交付給終端用戶(hù)。每種方案都包含詳細(xì)步驟,涵蓋模型導(dǎo)出、加載推理、服務(wù)部署和GUI集成等關(guān)鍵環(huán)節(jié),可根據(jù)不同應(yīng)用場(chǎng)景(高性能推理、Web服務(wù)或桌面應(yīng)用)靈活選擇。
在 Windows 上部署 PyTorch 模型主要有三種主流方式,取決于你的具體需求(是用于高性能推理、Web 服務(wù) API,還是桌面應(yīng)用程序)。
以下是三種最常用方案的詳細(xì)步驟:
方案一:使用 TorchScript (官方原生,適合 C++ 調(diào)用或高性能 Python 服務(wù))
適用場(chǎng)景:需要脫離 Python 解釋器依賴(lài)(C++ 部署),或者在 Python 中追求比原生 model.forward 更快的推理速度。
步驟 1: 導(dǎo)出模型為 TorchScript
在你的訓(xùn)練代碼或單獨(dú)的腳本中,將訓(xùn)練好的模型轉(zhuǎn)換為腳本格式。
import torch
import torchvision.models as models
# 1. 加載訓(xùn)練好的模型 (確保處于評(píng)估模式)
model = models.resnet18(weights='IMAGENET1K_V1') # 示例模型
model.eval()
# 2. 創(chuàng)建示例輸入 (用于追蹤或腳本化)
# 假設(shè)輸入是 batch_size=1, 3通道, 224x224的圖片
example_input = torch.rand(1, 3, 224, 224)
# 3. 跟蹤模式 (Tracing) - 適合控制流簡(jiǎn)單的模型
traced_script_module = torch.jit.trace(model, example_input)
# 或者 腳本模式 (Scripting) - 適合有復(fù)雜控制流(if/for)的模型
# traced_script_module = torch.jit.script(model)
# 4. 保存模型
traced_script_module.save("resnet18_windows.pt")
print("模型已導(dǎo)出為 resnet18_windows.pt")
步驟 2: 在 Windows 上部署 (Python 端加載)
創(chuàng)建一個(gè)獨(dú)立的推理腳本 inference.py,它不依賴(lài)訓(xùn)練代碼,只依賴(lài)導(dǎo)出的 .pt 文件。
import torch
import torchvision.transforms as transforms
from PIL import Image
# 1. 加載 TorchScript 模型
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = torch.jit.load("resnet18_windows.pt")
model.to(device)
model.eval()
# 2. 預(yù)處理圖片
transform = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
# 3. 推理
img = Image.open("test_image.jpg").convert("RGB")
input_tensor = transform(img).unsqueeze(0).to(device)
with torch.no_grad():
output = model(input_tensor)
print("預(yù)測(cè)結(jié)果:", output.argmax(dim=1).item())
步驟 3: (可選) C++ 部署 (完全脫離 Python)
如果你需要極致的性能或集成到現(xiàn)有的 C++ Windows 軟件中:
- 下載 LibTorch: 去 PyTorch 官網(wǎng) 選擇 “LibTorch”,操作系統(tǒng)選 “Windows”,語(yǔ)言選 “C++”,計(jì)算平臺(tái)選 “CUDA” (如果有顯卡) 或 “CPU”。
- 配置 Visual Studio:
- 新建 C++ 項(xiàng)目。
- 在屬性頁(yè)中配置
Include Directories和Library Directories指向解壓后的 LibTorch 文件夾 (include,lib)。 - 鏈接
torch_cpu.lib或torch_cuda.lib等相關(guān)庫(kù)。
- 編寫(xiě) C++ 代碼: 使用
torch::jit::load("model.pt")加載并推理。
方案二:構(gòu)建 Web API 服務(wù) (最常用,適合后端服務(wù))
適用場(chǎng)景:需要通過(guò) HTTP 請(qǐng)求調(diào)用模型(如前端網(wǎng)頁(yè)、移動(dòng)端 App 調(diào)用),使用 FastAPI 或 Flask。
步驟 1: 安裝依賴(lài)
打開(kāi) Windows PowerShell 或 CMD:
pip install fastapi uvicorn[standard] pillow python-multipart # 如果還沒(méi)裝 torch pip install torch torchvision
步驟 2: 創(chuàng)建main.py
from fastapi import FastAPI, File, UploadFile
import torch
import torchvision.transforms as transforms
from PIL import Image
import io
app = FastAPI()
# 全局加載模型 (避免每次請(qǐng)求都加載)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = torch.jit.load("resnet18_windows.pt") # 使用方案一中導(dǎo)出的模型
model.to(device)
model.eval()
transform = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
@app.post("/predict/")
async def predict(file: UploadFile = File(...)):
# 讀取圖片
image_data = await file.read()
image = Image.open(io.BytesIO(image_data)).convert("RGB")
# 預(yù)處理
input_tensor = transform(image).unsqueeze(0).to(device)
# 推理
with torch.no_grad():
output = model(input_tensor)
prediction = output.argmax(dim=1).item()
return {"filename": file.filename, "class_id": prediction}
# 啟動(dòng)命令: uvicorn main:app --reload --host 0.0.0.0 --port 8000
步驟 3: 運(yùn)行服務(wù)
在終端運(yùn)行:
uvicorn main:app --host 0.0.0.0 --port 8000
現(xiàn)在你可以訪問(wèn) http://localhost:8000/docs 查看 Swagger UI 界面并上傳測(cè)試圖片。
步驟 4: Windows 開(kāi)機(jī)自啟 (作為服務(wù))
為了讓它在后臺(tái)一直運(yùn)行:
- 使用 NSSM (Non-Sucking Service Manager) 工具。
- 下載 nssm.exe。
- 命令行運(yùn)行
nssm install PyTorchService。 - 在彈出的 GUI 中:
- Path: 填寫(xiě)你的 Python 路徑 (例如
C:\Users\YourName\venv\Scripts\python.exe)。 - Arguments: 填寫(xiě)
-m uvicorn main:app --host 0.0.0.0 --port 8000。 - Startup directory: 填寫(xiě)你的代碼所在文件夾。
- Path: 填寫(xiě)你的 Python 路徑 (例如
- 點(diǎn)擊 “Install service”,然后在 Windows 服務(wù)管理器中啟動(dòng)該服務(wù)。
方案三:打包為桌面 exe 程序 (適合交付給最終用戶(hù))
適用場(chǎng)景:需要發(fā)給沒(méi)有 Python 環(huán)境的普通用戶(hù)使用,帶圖形界面 (GUI)。
步驟 1: 安裝 PyInstaller 和 GUI 庫(kù)
pip install pyinstaller pyside6 # 或者 tkinter (內(nèi)置)
步驟 2: 編寫(xiě)帶 GUI 的推理腳本app.py
import sys
import torch
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton, QLabel, QFileDialog, QVBoxLayout, QWidget
from PySide6.QtGui import QPixmap
from PIL import Image
import torchvision.transforms as transforms
import io
# 加載模型 (全局)
model = torch.jit.load("resnet18_windows.pt")
model.eval()
transform = transforms.Compose([...]) # 同上
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("PyTorch Windows 演示")
layout = QVBoxLayout()
self.label = QLabel("請(qǐng)上傳圖片")
self.btn = QPushButton("選擇圖片并預(yù)測(cè)")
self.btn.clicked.connect(self.predict)
layout.addWidget(self.label)
layout.addWidget(self.btn)
container = QWidget()
container.setLayout(layout)
self.setCentralWidget(container)
def predict(self):
file_path, _ = QFileDialog.getOpenFileName(self, "選擇圖片", "", "Images (*.png *.jpg)")
if file_path:
img = Image.open(file_path).convert("RGB")
input_tensor = transform(img).unsqueeze(0)
with torch.no_grad():
out = model(input_tensor)
res = out.argmax(dim=1).item()
self.label.setText(f"預(yù)測(cè)類(lèi)別 ID: {res}")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
步驟 3: 打包成 EXE
由于 PyTorch 很大,打包需要特殊參數(shù)。
pyinstaller --noconfirm --onefile --windowed --add-data "resnet18_windows.pt;." app.py
注意:Windows 下 --add-data 使用分號(hào) ; 分隔,Linux/Mac 使用冒號(hào) :。
重要提示:
- 首次打包可能非常大(幾百 MB 甚至 1GB+),因?yàn)榘苏麄€(gè) PyTorch 庫(kù)。
- 如果遇到內(nèi)存錯(cuò)誤,嘗試添加
--exclude-module排除不需要的庫(kù),或者使用 UPX 壓縮(但有時(shí)會(huì)導(dǎo)致 PyTorch 崩潰,需測(cè)試)。 - 生成的
.exe文件在dist文件夾下,可以直接發(fā)給任何 Windows 電腦運(yùn)行(無(wú)需安裝 Python)。
Windows 部署特別注意事項(xiàng)
- 路徑問(wèn)題:
- Windows 路徑使用反斜杠
\,但在 Python 字符串中建議用正斜杠/或原始字符串r"C:\path"。 - 使用
os.path.join或pathlib來(lái)處理路徑,保證兼容性。
- Windows 路徑使用反斜杠
- CUDA 驅(qū)動(dòng):
- 如果使用 GPU 部署,目標(biāo)機(jī)器必須安裝與 PyTorch 版本匹配的 NVIDIA 顯卡驅(qū)動(dòng)。
- 不需要在目標(biāo)機(jī)器安裝 CUDA Toolkit (cuDNN 等已包含在 PyTorch wheel 包或 LibTorch 中),只要顯卡驅(qū)動(dòng)夠新即可。
- 防火墻:
- 如果是 Web API 部署,Windows Defender 防火墻可能會(huì)攔截 8000 端口。首次運(yùn)行時(shí)需允許通過(guò)防火墻。
- 性能優(yōu)化 (Windows 特有):
- 在推理前設(shè)置線程數(shù):
torch.set_num_threads(1)。Windows 上多線程有時(shí)反而因?yàn)樯舷挛那袚Q導(dǎo)致變慢,特別是在 CPU 推理時(shí)。 - 使用
torch.backends.cudnn.benchmark = True(僅限 NVIDIA GPU) 可以加速固定輸入的推理。
- 在推理前設(shè)置線程數(shù):
總結(jié)推薦
| 需求 | 推薦方案 | 難度 | 性能 |
|---|---|---|---|
| 內(nèi)部微服務(wù)/API | 方案二 (FastAPI + TorchScript) | ?? | ???? |
| 集成到 C++ 軟件 | 方案一 (LibTorch C++) | ????? | ????? |
| 給小白用戶(hù)的工具 | 方案三 (PyInstaller exe) | ??? | ??? |
| 快速原型驗(yàn)證 | 直接運(yùn)行 Python 腳本 | ? | ?? |
對(duì)于大多數(shù) Windows 部署場(chǎng)景,方案二 (FastAPI + TorchScript) 是最平衡、最穩(wěn)健的選擇。
以上就是在Windows上部署PyTorch模型的三種主流方法的詳細(xì)內(nèi)容,更多關(guān)于Windows部署PyTorch模型的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python使用defaultdict解決字典默認(rèn)值
本文主要介紹了Python使用defaultdict解決字典默認(rèn)值,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04
Ubuntu下使用python讀取doc和docx文檔的內(nèi)容方法
今天小編就為大家分享一篇Ubuntu下使用python讀取doc和docx文檔的內(nèi)容方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-05-05
python中opencv支持向量機(jī)的實(shí)現(xiàn)
本文主要介紹了python中opencv支持向量機(jī)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
把MySQL表結(jié)構(gòu)映射為Python中的對(duì)象的教程
這篇文章主要介紹了簡(jiǎn)單地把MySQL表結(jié)構(gòu)映射為Python中的對(duì)象的方法,用到了Python中的SQLAlchemy庫(kù),需要的朋友可以參考下2015-04-04
Python?clip與range函數(shù)保姆級(jí)使用教程
本文主要和大家介紹了詳解Python中clip與range函數(shù)的用法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參,希望能幫助到大家2022-06-06
Python?matplotlib實(shí)戰(zhàn)之氣泡圖繪制
氣泡圖是一種多變量的統(tǒng)計(jì)圖表,可以看作是散點(diǎn)圖的變形,這篇文章主要為大家介紹了如何使用Matplotlib繪制氣泡圖,需要的小伙伴可以參考下2023-08-08
flask SQLAlchemy連接數(shù)據(jù)庫(kù)及操作的實(shí)現(xiàn)
本文主要介紹了flask SQLAlchemy連接數(shù)據(jù)庫(kù)及操作的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03

