元設備¶
「元」設備是一種抽象設備,表示僅記錄中繼資料但不記錄實際資料的張量。元張量有兩個主要用例
- 模型可以載入到元設備上,讓您可以在不將實際參數載入記憶體的情況下載入模型的表示。如果您需要在載入實際資料之前對模型進行轉換,這會很有幫助。 
- 大多數運算都可以在元張量上執行,產生新的元張量,描述如果您在真實張量上執行運算會得到的結果。您可以使用它來執行抽象分析,而無需花費時間在計算或空間上來表示實際的張量。由於元張量沒有實際資料,因此您無法執行資料相依的運算,例如 - torch.nonzero()或- item()。在某些情況下,並非所有設備類型(例如,CPU 和 CUDA)對於某個運算都具有完全相同的輸出中繼資料;在這種情況下,我們通常更傾向於忠實地表示 CUDA 行為。
警告
雖然原則上元張量計算應該始終比等效的 CPU/CUDA 計算快,但許多元張量實作都是用 Python 實作的,並且尚未移植到 C++ 以提高速度,因此您可能會發現使用小型 CPU 張量可以獲得更低的絕對框架延遲。
使用元張量的慣例¶
可以透過指定 map_location='meta' 將物件使用 torch.load() 載入到元設備上
>>> torch.save(torch.randn(2), 'foo.pt')
>>> torch.load('foo.pt', map_location='meta')
tensor(..., device='meta', size=(2,))
如果您有一些任意程式碼在沒有明確指定設備的情況下執行一些張量建構,您可以使用 torch.device() 上下文管理器將其覆蓋為在元設備上建構
>>> with torch.device('meta'):
...     print(torch.randn(30, 30))
...
tensor(..., device='meta', size=(30, 30))
這對於 NN 模組建構特別有用,因為您通常無法明確傳入設備進行初始化
>>> from torch.nn.modules import Linear
>>> with torch.device('meta'):
...     print(Linear(20, 30))
...
Linear(in_features=20, out_features=30, bias=True)
您無法將元張量直接轉換為 CPU/CUDA 張量,因為元張量不儲存資料,而且我們不知道新張量的正確資料值是什麼
>>> torch.ones(5, device='meta').to("cpu")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NotImplementedError: Cannot copy out of meta tensor; no data!
使用工廠函式(例如 torch.empty_like())明確指定您希望如何填入遺漏的資料。
NN 模組有一個方便的方法 torch.nn.Module.to_empty(),允許您將模組移至另一個設備,並保留所有參數未初始化。您需要明確地手動重新初始化參數
>>> from torch.nn.modules import Linear
>>> with torch.device('meta'):
...     m = Linear(20, 30)
>>> m.to_empty(device="cpu")
Linear(in_features=20, out_features=30, bias=True)
torch._subclasses.meta_utils 包含未記載的工具,用於採用任意張量並建構具有高保真度的等效元張量。這些 API 仍處於實驗階段,可能會在任何時候以破壞 BC 的方式進行更改。