from_modules¶
- class tensordict.from_modules(*modules, as_module: bool = False, lock: bool = True, use_state_dict: bool = False, lazy_stack: bool = False, expand_identical: bool = False)¶
為了 ensebmle 學習/透過 vmap 期望應用程式的功能,擷取多個模組的參數。
- 參數:
modules (nn.Module 的序列) – 從中取得參數的模組。如果模組的結構不同,則需要惰性堆疊(請參閱下面的
lazy_stack
引數)。- 關鍵字引數:
as_module (bool, optional) – 如果
True
,將傳回TensorDictParams
實例,可用於在torch.nn.Module
中儲存參數。預設為False
。lock (bool, optional) – 如果
True
,產生的 tensordict 將會被鎖定。預設為True
。use_state_dict (bool, optional) –
如果
True
,將會使用模組中的 state-dict,並將其展開成具有模型樹狀結構的 TensorDict。預設為False
。注意
當必須使用 state-dict hook 時,這特別有用。
lazy_stack (bool, optional) –
參數應該以密集方式還是惰性方式堆疊。預設為
False
(密集堆疊)。注意
lazy_stack
和as_module
是互斥的功能。警告
在 lazy 和 non-lazy 輸出之間有一個關鍵差異,non-lazy 輸出將會使用所需的 batch size 重新實例化參數,而
lazy_stack
則會將參數表示為延遲堆疊。這表示當lazy_stack=True
時,原始參數可以安全地傳遞給優化器;但當它設置為True
時,需要傳遞新的參數。警告
雖然使用 lazy stack 來保留原始參數引用可能很誘人,但請記住,每次調用
get()
時,lazy stack 都會執行堆疊操作。這將需要記憶體(參數大小的 N 倍,如果構建圖形則更多)和時間來計算。這也意味著優化器將包含更多參數,並且像step()
或zero_grad()
這樣的操作將需要更長的時間來執行。通常,lazy_stack
應保留給極少數的使用情況。expand_identical (bool, optional) – 如果
True
且相同的參數(相同的標識)正在堆疊到自身,則會返回此參數的擴展版本。當lazy_stack=True
時,此參數將被忽略。
範例
>>> from torch import nn >>> from tensordict import from_modules >>> torch.manual_seed(0) >>> empty_module = nn.Linear(3, 4, device="meta") >>> n_models = 2 >>> modules = [nn.Linear(3, 4) for _ in range(n_models)] >>> params = from_modules(*modules) >>> print(params) TensorDict( fields={ bias: Parameter(shape=torch.Size([2, 4]), device=cpu, dtype=torch.float32, is_shared=False), weight: Parameter(shape=torch.Size([2, 4, 3]), device=cpu, dtype=torch.float32, is_shared=False)}, batch_size=torch.Size([2]), device=None, is_shared=False) >>> # example of batch execution >>> def exec_module(params, x): ... with params.to_module(empty_module): ... return empty_module(x) >>> x = torch.randn(3) >>> y = torch.vmap(exec_module, (0, None))(params, x) >>> assert y.shape == (n_models, 4) >>> # since lazy_stack = False, backprop leaves the original params untouched >>> y.sum().backward() >>> assert params["weight"].grad.norm() > 0 >>> assert modules[0].weight.grad is None
使用
lazy_stack=True
時,情況略有不同>>> params = TensorDict.from_modules(*modules, lazy_stack=True) >>> print(params) LazyStackedTensorDict( fields={ bias: Tensor(shape=torch.Size([2, 4]), device=cpu, dtype=torch.float32, is_shared=False), weight: Tensor(shape=torch.Size([2, 4, 3]), device=cpu, dtype=torch.float32, is_shared=False)}, exclusive_fields={ }, batch_size=torch.Size([2]), device=None, is_shared=False, stack_dim=0) >>> # example of batch execution >>> y = torch.vmap(exec_module, (0, None))(params, x) >>> assert y.shape == (n_models, 4) >>> y.sum().backward() >>> assert modules[0].weight.grad is not None