31-35【動手學深度學習】深度學習硬件

1. CPU和GPU

1.1 CPU

?CPU每秒鐘計算的浮點運算數為0.15,GPU為12。GPU的顯存很低,16GB(可能32G封頂),CPU可以一直插內存。

左邊是GPU(只能做些很簡單的游戲,視頻處理),中間是CPU,右邊是連接的通道,shared LLC第三級緩存(最后一級緩存)。

a和b都是向量,剛開始放在內存中,數據只有加載到寄存器中,才能參與運算,L3就是shared LLC。最快的是寄存器。

物理上直觀上看有四個核(見上面的圖),但是其實每個cpu有多個超線程(2個),所以有8個核,但是不一定提升性能,因為寄存器共用。

?1.2 GPU

框紅的就是一個核,十個(黃色線下)小核是一個大核,3060和3080的區別就是一個大核小,一個大核多。每個綠點是一個寄存單元,可以在一個綠點上開一個線程(上千個),(對于CPU來說,一個核算一個值,但是GPU是一個綠點算一個值)。就算一個綠點比GPU的一個核計算能力弱,但是GPU勝在綠點多。

/斜杠兩側分別是低端和高端CPU,GPU。GPU的顯存很貴,所以內存很小。CPU的可能一半都是在做邏輯控制,所以控制流更強,(因為CPU不經常計算一個矩陣,但是可能渲染一個html網頁)。

AMD的GPU游戲性能好,但是對高性能計算支持不算好。Intel有集成顯卡,ARM的CPU和GPU在嵌入式端(手機)常用。?

1.3 QA

①固定其他,增加數據(高質量數據)是提高泛化性最簡單和最有效的辦法,當有很多數據時,調參就沒那么有用?,固定數據集,調參有用

2. TPU和其他

ASIC容易造,不同于通用GPU,ASIC比較專用,容易開發?

一個Systolic Array相當于一個核?

3. 多GPU訓練

3.1 理論

數據并行:加入一個batch是128個樣本,有兩個GPU,每個GPU計算64個樣本的梯度再求和

模型并行:ResNet的前50層在GPU0,后50層在GPU1上。在前50層計算完結果后,傳給GPU1。transformer常用到。

四個卡計算效率差不多,并行性很好?

?3.2 代碼

3.2.1 復雜實現

%matplotlib inline
import torch
from torch import nn
from torch.nn import functional as F
from d2l import torch as d2l

簡單網絡

scale = 0.01
W1 = torch.randn(size=(20, 1, 3, 3)) * scale
b1 = torch.zeros(20)
W2 = torch.randn(size=(50, 20, 5, 5)) * scale
b2 = torch.zeros(50)
W3 = torch.randn(size=(800, 128)) * scale
b3 = torch.zeros(128)
W4 = torch.randn(size=(128, 10)) * scale
b4 = torch.zeros(10)
params = [W1, b1, W2, b2, W3, b3, W4, b4]def lenet(X, params):h1_conv = F.conv2d(input=X, weight=params[0], bias=params[1])h1_activation = F.relu(h1_conv)h1 = F.avg_pool2d(input=h1_activation, kernel_size=(2, 2), stride=(2, 2))h2_conv = F.conv2d(input=h1, weight=params[2], bias=params[3])h2_activation = F.relu(h2_conv)h2 = F.avg_pool2d(input=h2_activation, kernel_size=(2, 2), stride=(2, 2))h2 = h2.reshape(h2.shape[0], -1)h3_linear = torch.mm(h2, params[4]) + params[5]h3 = F.relu(h3_linear)y_hat = torch.mm(h3, params[6]) + params[7]return y_hatloss = nn.CrossEntropyLoss(reduction='none')

向多個設備分發參數

def get_params(params, device):new_params = [p.clone().to(device) for p in params]for p in new_params:p.requires_grad_()return new_paramsnew_params = get_params(params, d2l.try_gpu(0))
print('b1 weight:', new_params[1])
print('b1 grad:', new_params[1].grad)

?allreduce 函數將所有向量相加(相加到一塊GPU上),并將結果廣播給所有 GPU

def allreduce(data):for i in range(1, len(data)):data[0][:] += data[i].to(data[0].device)for i in range(1, len(data)):data[i] = data[0].to(data[i].device)data = [torch.ones((1, 2), device=d2l.try_gpu(i)) * (i + 1) for i in range(2)]
print('before allreduce:\n', data[0], '\n', data[1])
allreduce(data)
print('after allreduce:\n', data[0], '\n', data[1])

將一個小批量數據均勻地分布在多個 GPU 上

data = torch.arange(20).reshape(4, 5)
devices = [torch.device('cuda:0'), torch.device('cuda:1')]
split = nn.parallel.scatter(data, devices)
print('input:',data)
print('load into', devices)
print('output:', split)

def split_batch(X, y, devices):"""將`X`和`y`拆分到多個設備上"""assert X.shape[0] == y.shape[0]return (nn.parallel.scatter(X, devices), nn.parallel.scatter(y, devices))

?在一個小批量上實現多 GPU 訓練

def train_batch(X, y, device_params, devices, lr):X_shards, y_shards = split_batch(X, y, devices)# 在每個GPU上分別計算損失ls = [loss(lenet(X_shard,device_W), y_shard).sum() for X_shard, y_shard, device_W in zip(X_shards, y_shards, device_params)]for l in ls:  # 反向傳播在每個GPU上分別執行l.backward()with torch.no_grad():for i in range(len(device_params[0])):  # 層數allreduce([device_params[c][i].grad for c in range(len(devices))])# 在每個GPU上分別更新模型參數for param in device_params:d2l.sgd(param, lr, X.shape[0])   # 在這里,我們使用全尺寸的小批量

定義訓練函數

def train(num_gpus, batch_size, lr):train_iter, test_iter =  d2l.load_data_fashion_mnist(batch_size)devices = [d2l.try_gpu(i) for i in range(num_gpus)]# 將模型參數復制到num_gpus個GPUdevice_params = [get_params(params, d) for d in devices]num_epochs = 10animator = d2l.Animator('epoch', 'test acc', xlim=[1, num_epochs])timer = d2l.Timer()for epoch in range(num_epochs):timer.start()for X, y in train_iter:# 為單個小批量執行多GPU訓練train_batch(X, y, device_params, devices, lr)torch.cuda.synchronize()timer.stop()# 在GPU0上評估模型animator.add(epoch + 1, (d2l.evaluate_accuracy_gpu(lambda x: lenet(x, device_params[0]), test_iter, devices[0]),))print(f'test acc: {animator.Y[0][-1]:.2f}, {timer.avg():.1f} sec/epoch 'f'on {str(devices)}')

在單個GPU上運行

train(num_gpus=1, batch_size=256, lr=0.2)

?多個GPU

train(num_gpus=2, batch_size=256, lr=0.2)

小結

  • 有多種方法可以在多個GPU上拆分深度網絡的訓練。拆分可以在層之間、跨層或跨數據上實現。前兩者需要對數據傳輸過程進行嚴格編排,而最后一種則是最簡單的策略。
  • 數據并行訓練本身是不復雜的,它通過增加有效的小批量數據量的大小提高了訓練效率。
  • 在數據并行中,數據需要跨多個GPU拆分,其中每個GPU執行自己的前向傳播和反向傳播,隨后所有的梯度被聚合為一,之后聚合結果向所有的GPU廣播。
  • 小批量數據量更大時,學習率也需要稍微提高一些。

3.2.2 簡潔實現

import torch
from torch import nn
from d2l import torch as d2l

簡單網絡

def resnet18(num_classes, in_channels=1):"""稍加修改的 ResNet-18 模型"""def resnet_block(input_channels, output_channels, num_residuals, first_block=False):blk = []for i in range(num_residuals):if i == 0 and not first_block:# 第一個殘差塊且不是第一個block時,使用1x1卷積和下采樣blk.append(d2l.Residual(output_channels, use_1x1conv=True, strides=2))else:# 其他情況不使用1x1卷積blk.append(d2l.Residual(output_channels, output_channels))return nn.Sequential(*blk)# 網絡結構net = nn.Sequential(nn.Conv2d(in_channels, 64, kernel_size=3, stride=1, padding=1),nn.BatchNorm2d(64), nn.ReLU())# 添加殘差塊net.add_module("resnet_block1", resnet_block(64, 64, 2, first_block=True))net.add_module("resnet_block2", resnet_block(64, 128, 2))net.add_module("resnet_block3", resnet_block(128, 256, 2))net.add_module("resnet_block4", resnet_block(256, 512, 2))# 全局平均池化和全連接層net.add_module("global_avg_pool", nn.AdaptiveAvgPool2d((1, 1)))net.add_module("fc", nn.Sequential(nn.Flatten(), nn.Linear(512, num_classes)))return net# 創建網絡實例
net = resnet18(10)
devices = d2l.try_all_gpus()

網絡初始化

net = resnet18(10)
# 獲取GPU列表
devices = d2l.try_all_gpus()
# 我們將在訓練代碼實現中初始化網絡

訓練

def train(net, num_gpus, batch_size, lr):train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)devices = [d2l.try_gpu(i) for i in range(num_gpus)]def init_weights(m):if type(m) in [nn.Linear, nn.Conv2d]:nn.init.normal_(m.weight, std=0.01)net.apply(init_weights)# 在多個GPU上設置模型net = nn.DataParallel(net, device_ids=devices)trainer = torch.optim.SGD(net.parameters(), lr)loss = nn.CrossEntropyLoss()timer, num_epochs = d2l.Timer(), 10animator = d2l.Animator('epoch', 'test acc', xlim=[1, num_epochs])for epoch in range(num_epochs):net.train()timer.start()for X, y in train_iter:trainer.zero_grad()X, y = X.to(devices[0]), y.to(devices[0])l = loss(net(X), y)l.backward()trainer.step()timer.stop()animator.add(epoch + 1, (d2l.evaluate_accuracy_gpu(net, test_iter),))print(f'測試精度:{animator.Y[0][-1]:.2f},{timer.avg():.1f}秒/輪,'f'在{str(devices)}')

在單個GPU上訓練網絡

train(net, num_gpus=1, batch_size=256, lr=0.1)

在多個GPU上訓練網絡

train(net, num_gpus=2, batch_size=512, lr=0.2)

小結

  • 神經網絡可以在(可找到數據的)單GPU上進行自動評估。
  • 每臺設備上的網絡需要先初始化,然后再嘗試訪問該設備上的參數,否則會遇到錯誤。
  • 優化算法在多個GPU上自動聚合。

4. 分布式訓練

?t1最好是大t2 20%左右

當batchsize變大時,系統性能變好,但是批量越大,需要訓練更多epoch達到原始的訓練目標?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/81886.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/81886.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/81886.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【MySQL成神之路】MySQL常見命令匯總

目錄 MySQL常用命令總結 1. 數據庫操作 2. 表操作 3. 數據操作(DML) 4. 索引與優化 5. 用戶與權限管理 6. 備份與恢復 7. 事務控制 8. 常用函數 9. 系統狀態與日志 總結 MySQL常用命令總結 MySQL作為最流行的關系型數據庫之一,提供…

Dify的大語言模型(LLM) AI 應用開發平臺-本地部署

前言 今天閑著,搗鼓一下 Dify 這個開源平臺,在 mac 系統上,本地部署并運行 Dify 平臺,下面記錄個人在本地部署Dify 的過程。 Dify是什么? Dify是一個開源的大語言模型(LLM)應用開發平臺&#…

【論文閱讀】針對BEV感知的攻擊

Understanding the Robustness of 3D Object Detection with Bird’s-Eye-View Representations in Autonomous Driving 這篇文章是發表在CVPR上的一篇文章,針對基于BEV的目標檢測算法進行了兩類可靠性分析,即惡劣自然條件以及敵對攻擊。同時也提出了一…

SonarQube的核心作用與用途

SonarQube作為一個開源的代碼質量管理平臺,致力于持續分析代碼的健康狀態,幫助開發團隊提升代碼質量。以下是其核心作用與用途的詳細說明: 1、靜態代碼分析 SonarQube通過靜態代碼分析技術,自動識別代碼中的潛在問題。它能夠檢測…

AI工程師系列——面向copilot編程

前言 ? 筆者已經使用copilot協助開發有一段時間了,但一直沒有總結一個協助代碼開發的案例,特別是怎么問copilot,按照什么順序問,哪些方面可以高效的生成需要的代碼,這一次,筆者以IP解析需求為例,沉淀一個實踐案例,供大家參考 當然,其實也不局限于copilot本身,類似…

【軟件設計師】知識點簡單整理

文章目錄 數據結構與算法排序算法圖關鍵路徑 軟件工程決策表耦合類型 編程思想設計模式 計算機網絡域名請求過程 數據結構與算法 排序算法 哪些排序算法是穩定的算法?哪些不是穩定的算法,請舉出例子。 穩定排序算法:冒泡排序、插入排序、歸并排序、基數排序、計數…

FastAPI 支持文件下載和上傳

文章目錄 1. 文件下載處理1.1. 服務端處理1.1.1. 下載小文件1.1.2. 下載大文件(yield 支持預覽的)1.1.3. 下載大文件(bytes)1.1.4. 提供靜態文件服務1.1.5. 中文文件名錯誤 1.2. 客戶端處理1.2.1. 普通下載1.2.2. 分塊下載1.2.3. …

naive-ui切換主題

1、在App.vue文件中使用 <script setup lang"ts"> import Dashboard from ./views/dashboard/index.vue import { NConfigProvider, NGlobalStyle, darkTheme } from naive-ui import { useThemeStore } from "./store/theme"; // 獲取存儲的主題類…

Kotlin 協程 (三)

協程通信是協程之間進行數據交換和同步的關鍵機制。Kotlin 協程提供了多種通信方式&#xff0c;使得協程能夠高效、安全地進行交互。以下是對協程通信的詳細講解&#xff0c;包括常見的通信原語、使用場景和示例代碼。 1.1 Channel 定義&#xff1a;Channel 是一個消息隊列&a…

使用SQLite Studio導出/導入SQL修復損壞的數據庫

使用SQLite Studio導出/導入SQL修復損壞的數據庫 使用Zotero時遇到了數據庫損壞&#xff0c;在軟件中寸步難行&#xff0c;遂嘗試修復數據庫。 一、SQLite Studio簡介 SQLite Studio是一款專為SQLite數據庫設計的免費開源工具&#xff0c;支持Windows/macOS/Linux。相較于其…

【git config --global alias | Git分支操作效率提升實踐指南】

git config --global alias | Git分支操作效率提升實踐指南 背景與痛點分析 在現代軟件開發團隊中&#xff0c;Git分支管理是日常工作的重要組成部分。特別是在規范的開發流程中&#xff0c;我們經常會遇到類似 feature/user-management、bugfix/login-issue 或 per/cny/dev …

(八)深度學習---計算機視覺基礎

分類問題回歸問題聚類問題各種復雜問題決策樹√線性回歸√K-means√神經網絡√邏輯回歸√嶺回歸密度聚類深度學習√集成學習√Lasso回歸譜聚類條件隨機場貝葉斯層次聚類隱馬爾可夫模型支持向量機高斯混合聚類LDA主題模型 一.圖像數字化表示及建模基礎 二.卷積神經網絡CNN基本原…

在tensorflow源碼環境里,編譯出獨立的jni.so,避免依賴libtensorflowlite.so,從而實現apk體積最小化

需要在APP里使用tensorflow lite來運行PC端訓練的model.tlite&#xff0c;又想apk的體積最小&#xff0c;嘗試了如下方法&#xff1a; 1. 在gradle里配置 implementation("org.tensorflow:tensorflow-lite:2.16.1") 這樣會引入tensorflow.jar&#xff0c;最終apk的…

neo4j框架:java安裝教程

安裝使用neo4j需要事先安裝好java&#xff0c;java版本的選擇是一個犯難的問題。本文總結了在安裝java和使用Java過程中遇到的問題以及相應的解決方法。 Java的安裝包可以在java官方網站Java Downloads | Oracle 中國進行下載 以java 8為例&#xff0c;選擇最后一行的x64 compr…

[服務器備份教程] Rclone實戰:自動備份數據到阿里云OSS/騰訊云COS等對象存儲

更多服務器知識&#xff0c;盡在hostol.com 各位服務器的守護者們&#xff0c;咱們都知道&#xff0c;數據是數字時代的“黃金”&#xff0c;而服務器上的數據更是我們業務的命脈。可天有不測風云&#xff0c;硬盤可能會突然“壽終正寢”&#xff0c;手滑執行了“毀滅性”命令…

Nextjs App Router 開發指南

Next.js是一個用于構建全棧web應用的React框架。App Router 是 nextjs 的基于文件系統的路由器&#xff0c;它使用了React的最新特性&#xff0c;比如 Server Components, Suspense, 和 Server Functions。 術語 樹(Tree): 一種用于可視化的層次結構。例如&#xff0c;包含父…

山東大學計算機圖形學期末復習15——CG15

CG15 OpenGL緩沖區、讀寫操作以及混合&#xff08;Blending&#xff09; 一、OpenGL緩沖區概述 OpenGL中的緩沖區是用于存儲像素數據的內存區域&#xff0c;主要包括以下類型&#xff1a; 顏色緩沖區&#xff08;Color Buffer&#xff09;&#xff1a;存儲每個像素的顏色值…

html+css+js趣味小游戲~記憶卡片配對(附源碼)

下面是一個簡單的記憶卡片配對游戲的完整代碼&#xff0c;使用HTML、CSS和JavaScript實現&#xff1a; html <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"wid…

?個并發訪問量?較?的key在某個時間過期,在redis中這個時間過期什么意思

在 Redis 中&#xff0c;當提到一個鍵&#xff08;key&#xff09;“在這個時間過期”&#xff0c;指的是為該鍵設置了生存時間&#xff08;TTL, Time To Live&#xff09;或過期時間&#xff08;expiration time&#xff09;。一旦到達設定的過期時間&#xff0c;Redis 會自動…

【設計模式】- 行為型模式1

模板方法模式 定義了一個操作中的算法骨架&#xff0c;將算法的一些步驟推遲到子類&#xff0c;使得子類可以不改變該算法結構的情況下重定義該算法的某些步驟 【主要角色】&#xff1a; 抽象類&#xff1a;給出一個算法的輪廓和骨架&#xff08;包括一個模板方法 和 若干基…