みーのぺーじ

みーが趣味でやっているPCやソフトウェアについて.Python, Javascript, Processing, Unityなど.

PyTorch の Tensor.to() と nn.Module.to() の違い

RuntimeError: Placeholder storage has not been allocated on MPS device!

というエラーを修正するために調べたことをまとめます.

torch.Tensor は保存するデバイスを指定でき,Tensor.device プロパティで確認できます.

Tensor Attributes — PyTorch 2.0 documentation

デバイスを移動するには,Tensor.to() 関数を使用します.名前を見て勝手にデバイスを移動する関数だと思ったのですが,よく読むと指定したデバイスにコピーする関数であることに気づきました.

torch.Tensor.to — PyTorch 2.0 documentation

簡単なスクリプトで確認してみました.なお,MacOS で実行したので,デバイスタイプは cpu か mps となります.

from torch import tensor, backends

if __name__ == "__main__":
    if backends.mps.is_available():
        device = "mps"
        print("MPS is enabled")
    else:
        device = "cpu"
        print("MPS is not enabled.")
    print(f"device={device}")
    #
    a = tensor([1, 0, 0])
    assert a.device.type == "cpu"
    a = a.to(device) # important
    assert a.device.type == "mps"
    #
    b = tensor([0, 1, 0])
    assert b.device.type == "cpu"
    b.to(device)
    assert b.device.type == "cpu" # unchanged

Tensor a は mps にコピーされています.Tensor b はもともとの cpu のままです.

なお,同じ名前の関数は nn.Module にも存在しますが,こちらはデバイスを移動します.コピーしないので注意が必要です.

This method modifies the module in-place.
Module — PyTorch 2.0 documentation

このような点に注意しながら,計算に必要な TensorModule を同じデバイスに保存したところ,最初のエラーは解消されました.