Colab使用教學(超級詳細版)及Colab Pro/Pro+評測

2022-06-13 06:02:13
在下半年選修了機器學習的關鍵課程Machine learning and deep learning,但由於Macbook Pro顯示卡不支援cuda,因此無法使用GPU來訓練網路。教授推薦使用Google Colab作為訓練神經網路的平臺。在高強度的使用了Colab一段時間後,我把自己的個人感受和使用心得與大家分享,同時也給想要嘗試的同學詳細介紹Colab具體的上手方法。

一、Colab介紹

在第一次使用Colab時,最大的困難無疑是對整個平臺的陌生而導致無從下手,因此我首先介紹與Colab相關的基礎概念,以幫助大家更快地熟悉Colab平臺。

Colab是什麼?

Colab = Colaboratory(即合作實驗室),是谷歌提供的一個線上工作平臺,使用者可以直接通過瀏覽器執行python程式碼並與他人分享合作。Colab的主要功能當然不止於此,它還為我們提供免費的GPU。熟悉深度學習的同學們都知道:CPU計算力高但核數量少,善於處理線性序列,而GPU計算力低但核數量多,善於處理平行計算。在深度學習中使用GPU進行計算的速度要遠快於CPU,因此有高算力的GPU是深度學習的重要保證。由於不是所有GPU都支援深度計算(大部分的Macbook自帶的顯示卡都不支援),同時顯示卡設定的高低也決定了計算力的大小,因此Colab最大的優勢在於我們可以「借用」谷歌免費提供的GPU來進行深度學習。
綜上:Colab = "python版"Google doc + 免費GPU

Colab相關的概念

Jupyter Notebook:在Colab中,python程式碼的執行是基於.ipynb檔案,也就是Jupyter Notebook格式的python檔案。這種筆電檔案與普通.py檔案的區別是可以分塊執行程式碼並立刻得到輸出,同時也可以很方便地新增註釋,這種互動式操作十分適合一些輕量的任務。
具體關於Jupyter Notebook的資訊可以檢視下面官網的連結:https://jupyter.org/
程式碼執行程式:程式碼執行程式就是Colab在雲端的"伺服器"。簡單來說,我們先在筆電寫好需要執行的程式碼,連線到程式碼執行程式,然後Colab會在雲端執行程式碼,最後把結果傳回瀏覽器。
範例空間:連線到程式碼執行程式後,Colab需要為其分配範例空間(Instance),可以簡單理解為執行筆電而建立的"虛擬機器器",其中包含了執行ipynb檔案時的預設設定、環境變數、自帶的庫等等。

二、Colab工作流程

介紹完了基本概念,下面我們來演示具體如何使用Colab

準備工作

首先我們需要建立一個谷歌賬戶,申請谷歌賬戶需要能接受簡訊的手機號碼。作者在寫這篇文章時親自進行了一次測試,發現目前不能通過中國手機來建立賬戶,但是賬號在建立後可以改綁中國手機。由於躍牆、如何申請谷歌賬戶不是本文的寫作目的,因此這裡就不作展開了,我個人猜測萬能的某寶之類應該有解決辦法。
Colab一般配合Google Drive使用(下文會提到這一點)。因此如有必要,我建議拓展谷歌雲端硬碟的儲存空間,個人認為價效比較高的是基本版或標準版。在購買完額外的空間後,頭像外部會出現一個四色光環,就像作者一樣。

新建筆電

有兩種方法可以新建一個筆電,第一種是在在雲端硬碟中右鍵建立。
如果右鍵後沒有發現有這一個選項,那是因為雲端硬碟還沒有安裝Colab。這時在右擊後選擇「關聯更多應用」,然後搜尋colab並下載,之後就可以通過右鍵建立了。
 
 
第二種方法是直接在瀏覽器中輸入https://colab.research.google.com,進入Colab的頁面後點選新建筆電即可。使用這種方法新建的筆電時,會在雲端硬碟的根目錄自動建立一個叫Colab Notebook的資料夾,新建立的筆電就儲存在這個資料夾中。
 

載入筆電

可以開啟雲端硬碟中的已經存在的筆電,還可以從Github中匯入筆電。如果關聯了Github賬戶,可以選擇一個賬戶中的Project,如果其中有ipynb檔案就可以在Colab中開啟。注意:關聯Github不是把Github中的專案資料夾載入到範例空間!
 

筆電介面

 
標題:筆電的名稱
程式碼塊:分塊執行的程式碼
檔案瀏覽:Colab為筆電分配的範例空間
程式碼執行程式:用於執行筆電程式的伺服器
程式碼段:常用的程式碼段,比如裝載雲端硬碟
命令面板:常用的命令,比如查詢/替換
終端:檔案瀏覽下的終端(非常卡,不建議使用)

連執行緒式碼執行程式

點選連線按鈕即可在5s左右的時間內連線到程式碼執行程式,此時可以看到消耗的RAM和磁碟
RAM:虛擬機器器執行記憶體,更大記憶體意味著更大的算力(之後會在Colab Pro中介紹)
磁碟:虛擬機器器檔案的儲存空間,要注意的是購買更多雲端硬碟儲存空間不能增加可用磁碟空間
 
在開啟筆電後,我們預設的檔案路徑是"/content",這個路徑也是執行筆電時的路徑,同時我們一般把用到的各種檔案也儲存在這個路徑下。在點選".."後即可返回檢視根目錄"/"(如下圖),可以看到根目錄中儲存的是一些虛擬機器器的環境變數和預裝的庫等等。不要隨意修改根目錄中的內容,以避免執行出錯,我們所有的操作都應在"/content"中進行。

執行程式碼塊

.ipynb檔案通過的程式碼塊來執行程式碼,同時支援通過"!<command>"的方式來執行UNIX終端命令(比如"!ls"可以檢視當前目錄下的檔案)。Colab已經預裝了大多數常見的深度學習庫,比如pytorch,tensorflow等等,如果有需要額外安裝的庫可以通過"!pip3 install <package>"命令來安裝。下面是一些常見的命令。
# 載入雲端硬碟 
from google.colab import drive 
drive.mount('/content/drive') 

# 檢視分配到的GPU 
gpu_info = !nvidia-smi 
gpu_info = '\n'.join(gpu_info) 
if gpu_info.find('failed') >= 0: 
    print('Not connected to a GPU') 
else: 
    print(gpu_info) 

# 安裝python包 
!pip3 install <package>
點選「播放」按鈕執行程式碼塊。程式碼塊開始執行後,按鈕就會進入轉圈的狀態,表示「正在執行」,外部的圓圈是實線。如果在有程式碼塊執行的情況下繼續點選其他程式碼塊的「播放」按鈕,則這些程式碼塊進入「等待執行」的狀態,按鈕也就會進入轉圈的狀態,但外部的圓圈是虛線。在當前程式碼塊結束後,會之前按照點選的順序依次執行這些程式碼塊。

設定筆電的執行時型別

筆電在開啟時的預設硬體加速器是None,執行規格是標準。在深度學習中,我們希望使用GPU來進行深度計算,同時如果購買了pro,我們希望使用高記憶體模式。點選程式碼執行程式,然後點選「更改執行時型別即可」。由於免費的使用者所能使用的GPU執行時有限,由於免費的使用者所能使用的GPU執行時有限,因此建議在模型訓練結束後調回None模式或直接結束對談。
如果希望主動斷開程式碼執行程式,則點選程式碼執行程式後選擇「斷開連線並刪除執行時」即可。
 

管理對談Session

對談就是當前連線到程式碼執行程式的筆電,通過點選「管理對談」即可檢視當前的所有對談,點選「終止」即可斷開程式碼執行程式。使用者所能連線的對談數量是有限的,因此到達上限時再開啟新對談需要主動斷開之前的對談。
 

三、Colab重要特性

在這一部分,我們進一步瞭解Colab平臺的一些重要特性和使用Colab訓練模型時的一些策略

資源使用的限制

Google Colab為使用者提供免費的GPU,因此資源使用必然會受到限制(即使是Colab Pro+使用者也不例外),而這種限制無處不在。
有限的範例空間:範例空間的記憶體和磁碟都是有限制的,如果模型訓練的過程中超過了記憶體或磁碟的限制,那麼程式執行就會中斷並報錯。範例空間內的檔案儲存不是永久的,當程式碼執行程式被斷開時,範例空間內的所有資源都會被釋放(我們在"/content"目錄下上傳的檔案也會全部消失)。
 
有限的連線時間:筆電連線到程式碼執行程式的時長是有限制的,這體現在三個方面:如果關閉瀏覽器,程式碼執行程式會在短時間內斷開而不是在後臺繼續執行(這個「短時間」大概在幾分鐘左右,如果只是切換一下wifi之類是不會有影響的);如果空閒狀態過長(無互動操作或正在執行的程式碼塊),則會立即斷開連線;如果連線時長到達上限(免費使用者最長連線12小時),也會立刻斷開連線。
 
有限的GPU執行時:無論是免費使用者還是colab pro使用者,每天所能使用的GPU執行時間都是有限的。到達時間上限後,程式碼執行程式將被立刻斷開且使用者將被限制在當天繼續使用任何形式的GPU(無論是否為高RAM形式)。在這種情況下我們只能等待第二天重置。
 
頻繁的互動檢測:當一段時間沒有檢測到活動時,Colab就會進行互動檢測,如果長時間不點選人機身份驗證,程式碼執行程式就會斷開。此外,如果頻繁地執行「斷開-連線」程式碼執行程式,也會出現人機身份驗證。
 
有限的對談數量:每個使用者所能開啟的對談數量都是有限的,免費使用者只能開啟1個對談,Pro使用者則可以開啟多個對談。不同的使用者可以在一個筆電上可以進行多個對談,但只能有一個程式碼塊開始執行。如果某個程式碼塊已經開始執行,另一個使用者連線到筆電的對談會顯示「忙碌狀態」,需要等待程式碼塊執行完後才能執行其他的程式碼塊。注意:掉線重連、切換網路、重新整理頁面等操作也會使筆電進入「忙碌狀態」。
正常情況
忙碌狀態

如何合理使用資源?

  1. 將訓練過後的模型紀錄檔和其他重要的檔案儲存到谷歌雲盤,而不是原生的範例空間
  2. 執行的程式碼必須支援「斷點續傳」能力,簡單來說就是必須定義類似checkpoint功能的函數;假設我們一共需要訓練40個epochs,在第30個epoch掉線了之後模型能夠從第30個epoch開始訓練而不是從頭再來
  3. 僅在模型訓練時開啟GPU模式,在構建模型或其他非必要情況下使用None模式
  4. 在網路穩定的情況下開始訓練,每隔一段時間檢視一下訓練的情況
  5. 註冊多個免費的谷歌賬號交替使用

四、Colab專案組織

在正式進入範例演示之前,最後簡單介紹一下在Colab上組織專案的方法

載入資料集

深度學習中,資料集一般由超大量的資料組成,如何在Colab上快速載入資料集?
1. 將整個資料集從本地上傳到範例空間
理論可行但實際不可取。經過作者實測,無論是上傳壓縮包還是資料夾,這種方法都是非常的慢,對於較大的資料集完全不具備可操作性。
2. 將整個資料集上傳到谷歌硬碟,掛載谷歌雲盤的之後直接讀取雲盤內的資料集
理論可行但風險較大。根據谷歌的說明,Colab讀取雲盤的I/O次數也是有限制的,太瑣碎的I/O會導致出現「配額限制」。如果資料集包含大量的子資料夾,也很容易出現掛載錯誤。
3. 將資料集以壓縮包形式上傳到谷歌雲盤,然後解壓到Colab範例空間
實測可行。掛載雲盤不消耗時間,解壓所需的時間遠遠小於上傳資料集的時間
此外,由於範例空間會定期釋放,因此模型訓練完成後的紀錄檔也應該存放在谷歌雲盤上。綜上所述,谷歌雲盤是使用Colab必不可少的一環,由於免費的雲盤只有15個G,因此個人建議至少拓展到基本版。

執行Github專案

Colab的基本執行單位是Jupyter Notebook,如何在一個notebook上執行一個複雜的Github專案呢?
首先建立多個筆電來對應多個py模組是肯定不行的,因為不同的筆電會對應不同範例空間,而同一個專案的不同模組應放在同一個範例空間中。為解決這個問題,可以考慮以下幾種方法。
1. 克隆git倉庫到範例空間或雲盤,通過指令碼的方式直接執行專案的主程式
# 克隆倉庫到/content/my-repo目錄下 
!git clone https://github.com/my-github-username/my-git-repo.git %cd my-git-repo !./train.py --logdir /my/log/path --data_root /my/data/root --resume
2. 克隆git倉庫到範例空間或雲盤,把主程式中的程式碼用函數封裝,然後在notebook中呼叫這些函數
from train import my_training_method 
my_training_method(arg1, arg2, ...)
由於筆電預設的路徑是"/content",因此可能需要修改系統路徑後才能直接匯入
import sys 
sys.path.append('/content/my-git-repo') # 把git倉庫的目錄新增到系統目錄
3. 克隆git倉庫到範例空間或雲盤,把原來的主程式模組直接複製到筆電中
類似於第二種方法,需要將git倉庫路徑新增到系統路徑,否則會找不到匯入的模組

如何處理簡單專案?

如果只有幾個輕量的模組,也不打算使用git進行版本管理,則直接上傳到範例空間即可

五、範例演示

下面以我在這個學期完成的專案為例,向大家完整展示Colab的使用過程。PS:真不是推銷自己的專案,而是目前我只做了這一個專案(ಥ_ಥ)
點選以後就可以在谷歌雲盤的「與我共用」看到這個資料夾"zhihu_colab",將這個資料夾的快捷方式新增到自己的雲盤即可(右鍵資料夾「將快捷方式新增到雲盤」,選擇「我的雲端硬碟」)
資料夾"zhihu_colab"中包含了資料集"ROD-synROD.tar"和程式碼"mldl_project"(以及這部分我寫的notebook)
首先載入自己的谷歌雲盤
from google.colab import drive 
drive.mount('/content/drive')
載入成功以後(可以點一下重新整理按鈕)就可以看到雲盤在範例空間中出現了
谷歌雲盤預設的載入路徑是"/content/drive/MyDrive"
 
在當前目錄下("/content")建立一個叫datasets的資料夾,並將"zhihu_colab"中的資料集解壓到這個資料夾
!mkdir /content/datasets !tar -xvf "/content/drive/MyDrive/zhihu_colab/ROD-synROD.tar" -C "/content/datasets"
檢視一下自己分到的GPU是什麼,具體的資訊很長,只要看中間顯示卡部分就行了。
gpu_info = !nvidia-smi 
gpu_info = '\n'.join(gpu_info) 
if gpu_info.find('failed') >= 0: 
    print('Not connected to a GPU') 
else: 
    print(gpu_info)
 
哇哦,我們作為高貴的Pro使用者果然分到了最好的P100