torch.nested¶
簡介¶
警告
巢狀 Tensor 的 PyTorch API 處於原型階段,近期將會變更。
NestedTensor 允許使用者將 Tensor 清單封裝到單一、有效率的資料結構中。
對輸入 Tensor 的唯一限制是它們的維度必須相符。
這能夠實現更有效率的中繼資料表示,並能存取專為此目的建立的核心。
NestedTensor 的一個應用是表達各個領域中的序列資料。傳統方法是填充可變長度的序列,而 NestedTensor 允許使用者繞過填充。在巢狀 tensor 上呼叫操作的 API 與常規 torch.Tensor
的 API 沒有區別,這應該允許與現有模型無縫整合,主要區別在於 輸入的建構。
由於這是一項原型功能,支援的操作仍然有限。但是,我們歡迎提出問題、功能請求和貢獻。有關貢獻的更多資訊,請參閱 此 Readme。
建構¶
建構很簡單,只需將 Tensor 清單傳遞給 torch.nested.nested_tensor
建構函式即可。
>>> a, b = torch.arange(3), torch.arange(5) + 3
>>> a
tensor([0, 1, 2])
>>> b
tensor([3, 4, 5, 6, 7])
>>> nt = torch.nested.nested_tensor([a, b])
>>> nt
nested_tensor([
tensor([0, 1, 2]),
tensor([3, 4, 5, 6, 7])
])
資料類型、裝置以及是否需要梯度可以透過通常的關鍵字引數來選擇。
>>> nt = torch.nested.nested_tensor([a, b], dtype=torch.float32, device="cuda", requires_grad=True)
>>> nt
nested_tensor([
tensor([0., 1., 2.], device='cuda:0', requires_grad=True),
tensor([3., 4., 5., 6., 7.], device='cuda:0', requires_grad=True)
], device='cuda:0', requires_grad=True)
與 torch.as_tensor
類似,torch.nested.as_nested_tensor
可用於保留從傳遞給建構子的 tensors 的 autograd 歷史記錄。 更多資訊請參考 巢狀張量建構子與轉換函式 一節。
為了形成一個有效的 NestedTensor,所有傳遞的 Tensors 需要在維度上匹配,但其他屬性則不需要。
>>> a = torch.randn(3, 50, 70) # image 1
>>> b = torch.randn(3, 128, 64) # image 2
>>> nt = torch.nested.nested_tensor([a, b], dtype=torch.float32)
>>> nt.dim()
4
如果其中一個維度不匹配,建構子將會拋出錯誤。
>>> a = torch.randn(50, 128) # text 1
>>> b = torch.randn(3, 128, 64) # image 2
>>> nt = torch.nested.nested_tensor([a, b], dtype=torch.float32)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: All Tensors given to nested_tensor must have the same dimension. Found dimension 3 for Tensor at index 1 and dimension 2 for Tensor at index 0.
請注意,傳遞的 Tensors 會被複製到連續的記憶體區塊中。產生的 NestedTensor 會分配新的記憶體來儲存它們,並且不會保留引用。
目前我們僅支援單層巢狀結構,即簡單的 tensors 平面列表。未來我們可以添加對多層巢狀結構的支援,例如完全由 tensors 列表組成的列表。 請注意,對於此擴充,重要的是在條目之間保持均勻的巢狀結構層級,以便產生的 NestedTensor 具有明確定義的維度。 如果您需要此功能,請隨時開啟一個功能請求,以便我們可以追蹤並據此進行規劃。
size¶
即使 NestedTensor 不支援 .size()
(或 .shape
),如果維度 i 是規則的,則它支援 .size(i)
。
>>> a = torch.randn(50, 128) # text 1
>>> b = torch.randn(32, 128) # text 2
>>> nt = torch.nested.nested_tensor([a, b], dtype=torch.float32)
>>> nt.size(0)
2
>>> nt.size(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: Given dimension 1 is irregular and does not have a size.
>>> nt.size(2)
128
如果所有維度都是規則的,則 NestedTensor 在語義上應與常規的 torch.Tensor
無法區分。
>>> a = torch.randn(20, 128) # text 1
>>> nt = torch.nested.nested_tensor([a, a], dtype=torch.float32)
>>> nt.size(0)
2
>>> nt.size(1)
20
>>> nt.size(2)
128
>>> torch.stack(nt.unbind()).size()
torch.Size([2, 20, 128])
>>> torch.stack([a, a]).size()
torch.Size([2, 20, 128])
>>> torch.equal(torch.stack(nt.unbind()), torch.stack([a, a]))
True
未來我們可能會更容易檢測到這種情況並無縫轉換。
如果您需要此功能(或任何其他相關功能),請開啟一個功能請求。
unbind¶
unbind
允許您檢索組成分量的視圖。
>>> import torch
>>> a = torch.randn(2, 3)
>>> b = torch.randn(3, 4)
>>> nt = torch.nested.nested_tensor([a, b], dtype=torch.float32)
>>> nt
nested_tensor([
tensor([[ 1.2286, -1.2343, -1.4842],
[-0.7827, 0.6745, 0.0658]]),
tensor([[-1.1247, -0.4078, -1.0633, 0.8083],
[-0.2871, -0.2980, 0.5559, 1.9885],
[ 0.4074, 2.4855, 0.0733, 0.8285]])
])
>>> nt.unbind()
(tensor([[ 1.2286, -1.2343, -1.4842],
[-0.7827, 0.6745, 0.0658]]), tensor([[-1.1247, -0.4078, -1.0633, 0.8083],
[-0.2871, -0.2980, 0.5559, 1.9885],
[ 0.4074, 2.4855, 0.0733, 0.8285]]))
>>> nt.unbind()[0] is not a
True
>>> nt.unbind()[0].mul_(3)
tensor([[ 3.6858, -3.7030, -4.4525],
[-2.3481, 2.0236, 0.1975]])
>>> nt
nested_tensor([
tensor([[ 3.6858, -3.7030, -4.4525],
[-2.3481, 2.0236, 0.1975]]),
tensor([[-1.1247, -0.4078, -1.0633, 0.8083],
[-0.2871, -0.2980, 0.5559, 1.9885],
[ 0.4074, 2.4855, 0.0733, 0.8285]])
])
請注意,nt.unbind()[0]
不是副本,而是底層記憶體的切片,代表 NestedTensor 的第一個條目或組成分量。
巢狀張量建構子與轉換函式¶
以下函式與巢狀張量相關
- torch.nested.nested_tensor(tensor_list, *, dtype=None, layout=None, device=None, requires_grad=False, pin_memory=False)[原始碼][原始碼]¶
從
tensor_list
(一個 tensors 列表)建構一個沒有 autograd 歷史記錄的巢狀張量(也稱為“葉張量”,請參閱 Autograd 機制)。- 參數
tensor_list (List[array_like]) – tensors 列表,或任何可以傳遞給 torch.tensor 的東西,
dimensionality. (其中列表中的每個元素 具有相同的) –
- 關鍵字參數
dtype (
torch.dtype
, optional) – 返回的巢狀張量所需的類型。預設值:如果為 None,則與列表中最左側 tensor 的torch.dtype
相同。layout (
torch.layout
, optional) – 返回的巢狀張量所需的 layout。 僅支援 strided 和 jagged layouts。預設值:如果為 None,則為 strided layout。device (
torch.device
, optional) – 返回的巢狀張量所需的裝置。預設值:如果為 None,則與列表中最左側 tensor 的torch.device
相同requires_grad (bool, optional) – 如果 autograd 應記錄返回的巢狀張量上的操作。預設值:
False
。pin_memory (bool, optional) – 如果設定,返回的巢狀張量將分配在 pinned memory 中。僅適用於 CPU tensors。預設值:
False
。
- 返回類型
範例
>>> a = torch.arange(3, dtype=torch.float, requires_grad=True) >>> b = torch.arange(5, dtype=torch.float, requires_grad=True) >>> nt = torch.nested.nested_tensor([a, b], requires_grad=True) >>> nt.is_leaf True
- torch.nested.as_nested_tensor(ts, dtype=None, device=None, layout=None)[原始碼][原始碼]¶
從 tensor 或 tensors 的列表/元組建構一個保留 autograd 歷史記錄的巢狀張量。
如果傳遞了巢狀張量,則將直接返回它,除非 device / dtype / layout 不同。請注意,轉換 device / dtype 將導致複製,而此函數目前不支援轉換 layout。
如果傳遞了非巢狀張量,則將其視為一致大小的組成分量批次。 如果傳遞的 device / dtype 與輸入的不同,或者如果輸入不連續,則會產生複製。 否則,將直接使用輸入的儲存空間。
如果提供了 tensor 列表,則在建構巢狀張量期間始終會複製列表中的 tensors。
- 參數
ts (Tensor or List[Tensor] or Tuple[Tensor]) – 要視為巢狀張量的 tensor OR 具有相同 ndim 的 tensors 列表/元組
- 關鍵字參數
dtype (
torch.dtype
, optional) – 返回的巢狀張量所需的類型。預設值:如果為 None,則與列表中最左側 tensor 的torch.dtype
相同。device (
torch.device
, optional) – 返回的巢狀張量所需的裝置。預設值:如果為 None,則與列表中最左側 tensor 的torch.device
相同layout (
torch.layout
, optional) – 返回的巢狀張量所需的 layout。 僅支援 strided 和 jagged layouts。預設值:如果為 None,則為 strided layout。
- 返回類型
範例
>>> a = torch.arange(3, dtype=torch.float, requires_grad=True) >>> b = torch.arange(5, dtype=torch.float, requires_grad=True) >>> nt = torch.nested.as_nested_tensor([a, b]) >>> nt.is_leaf False >>> fake_grad = torch.nested.nested_tensor([torch.ones_like(a), torch.zeros_like(b)]) >>> nt.backward(fake_grad) >>> a.grad tensor([1., 1., 1.]) >>> b.grad tensor([0., 0., 0., 0., 0.]) >>> c = torch.randn(3, 5, requires_grad=True) >>> nt2 = torch.nested.as_nested_tensor(c)
- torch.nested.to_padded_tensor(input, padding, output_size=None, out=None) Tensor ¶
透過填補
input
巢狀張量,返回一個新的 (非巢狀) 張量。 前導條目將會以巢狀資料填滿,而尾隨條目將會被填補。警告
to_padded_tensor()
總是複製底層資料,因為巢狀和非巢狀張量在記憶體佈局上有所不同。- 參數
padding (float) – 尾隨條目的填補值。
- 關鍵字參數
範例
>>> nt = torch.nested.nested_tensor([torch.randn((2, 5)), torch.randn((3, 4))]) nested_tensor([ tensor([[ 1.6862, -1.1282, 1.1031, 0.0464, -1.3276], [-1.9967, -1.0054, 1.8972, 0.9174, -1.4995]]), tensor([[-1.8546, -0.7194, -0.2918, -0.1846], [ 0.2773, 0.8793, -0.5183, -0.6447], [ 1.8009, 1.8468, -0.9832, -1.5272]]) ]) >>> pt_infer = torch.nested.to_padded_tensor(nt, 0.0) tensor([[[ 1.6862, -1.1282, 1.1031, 0.0464, -1.3276], [-1.9967, -1.0054, 1.8972, 0.9174, -1.4995], [ 0.0000, 0.0000, 0.0000, 0.0000, 0.0000]], [[-1.8546, -0.7194, -0.2918, -0.1846, 0.0000], [ 0.2773, 0.8793, -0.5183, -0.6447, 0.0000], [ 1.8009, 1.8468, -0.9832, -1.5272, 0.0000]]]) >>> pt_large = torch.nested.to_padded_tensor(nt, 1.0, (2, 4, 6)) tensor([[[ 1.6862, -1.1282, 1.1031, 0.0464, -1.3276, 1.0000], [-1.9967, -1.0054, 1.8972, 0.9174, -1.4995, 1.0000], [ 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000], [ 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000]], [[-1.8546, -0.7194, -0.2918, -0.1846, 1.0000, 1.0000], [ 0.2773, 0.8793, -0.5183, -0.6447, 1.0000, 1.0000], [ 1.8009, 1.8468, -0.9832, -1.5272, 1.0000, 1.0000], [ 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000]]]) >>> pt_small = torch.nested.to_padded_tensor(nt, 2.0, (2, 2, 2)) RuntimeError: Value in output_size is less than NestedTensor padded size. Truncation is not supported.
支援的操作¶
在本節中,我們總結了目前 NestedTensor 上支援的操作以及它們的任何約束。
PyTorch 操作 |
約束 |
---|---|
支援兩個 (>= 3d) 巢狀張量之間的矩陣乘法,其中最後兩個維度是矩陣維度,並且前導 (批次) 維度具有相同的大小 (即,目前不支援批次維度的廣播)。 |
|
支援兩個 3-d 巢狀張量的批次矩陣乘法。 |
|
支援 3-d 巢狀輸入和一個密集的 2-d 權重矩陣。 |
|
支援沿著所有維度(除了 dim=0)的 softmax。 |
|
行為與在常規張量上相同。 |
|
行為與在常規張量上相同。 |
|
|
行為與在常規張量上相同。 |
|
行為與在常規張量上相同。 |
|
行為與在常規張量上相同。 |
行為與在常規張量上相同。 |
|
行為與在常規張量上相同。 |
|
行為與在常規張量上相同。 |
|
行為與在常規張量上相同。 |
|
支援兩個巢狀張量的元素減法。 |
|
支援兩個巢狀張量的元素加法。 支援將標量加到巢狀張量。 |
|
支援兩個巢狀張量的元素乘法。 支援將巢狀張量乘以標量。 |
|
支援沿著所有維度進行選擇。 |
|
行為與在常規張量上相同。 |
|
|
行為與在常規張量上相同。 |
僅支援沿著 |
|
支援重新塑形,且 |
|
與 |
|
支援除了 |
|
新形狀的規則與 |
|
行為與常規張量的行為類似;返回一個新的空巢狀張量 (即,具有未初始化的值),並與輸入的巢狀結構相符。 |
|
行為與常規張量的行為類似;返回一個新的巢狀張量,其值根據標準常態分佈隨機初始化,並與輸入的巢狀結構相符。 |
|
行為與常規張量的行為類似;返回一個新的巢狀張量,其所有值均為零,並與輸入的巢狀結構相符。 |
|
|