torch.package.PackageExporter.save_source_file() の詳細解説と代替方法


torch.package.PackageExporter.save_source_file() は、PyTorch Package における重要な機能の一つです。この関数は、モデルやデータセットなどのソースファイルをパッケージ内に保存するために使用されます。

使用方法

torch.package.PackageExporter.save_source_file(
    package_name: str,
    filename: str,
    source_code: str,
    location: Optional[str] = None
)

引数

  • location: 保存する場所 (デフォルトはパッケージルート)
  • source_code: 保存するソースコード
  • filename: ファイル名
  • package_name: 保存するパッケージの名前

動作

この関数は、指定されたソースコードをパッケージ内の指定されたファイル名で保存します。location 引数を指定することで、保存場所をパッケージルート以外のディレクトリに変更できます。

import torch.package as package

# モデルのソースコード
model_code = """
import torch.nn as nn

class MyModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.linear = nn.Linear(10, 1)

    def forward(self, x):
        return self.linear(x)
"""

# パッケージの作成
package_name = "my_package"
package = package.Package(package_name)

# モデルのソースファイルを保存
package.save_source_file(
    package_name,
    "my_model.py",
    model_code
)

# パッケージの保存
package.save()

この例では、MyModel というモデルのソースコードを my_model.py というファイル名で my_package というパッケージ内に保存します。

  • ソースファイルを保存する前に、そのファイルがすでに存在しないことを確認する必要があります。
  • 保存されたソースファイルは、パッケージをロードしたときに自動的にインポートされます。


import torch.package as package

# モデルのソースコード
model_code = """
import torch.nn as nn

class MyModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.linear = nn.Linear(10, 1)

    def forward(self, x):
        return self.linear(x)
"""

# パッケージの作成
package_name = "my_package"
package = package.Package(package_name)

# モデルのソースファイルを保存
package.save_source_file(
    package_name,
    "my_model.py",
    model_code
)

# パッケージの保存
package.save()

説明

例 2: データセットのソースファイルを保存

import torch.package as package
import torch.utils.data as data

# データセットのソースコード
dataset_code = """
class MyDataset(data.Dataset):
    def __init__(self):
        # データの読み込み
        self.data = ...

    def __getitem__(self, index):
        # データの取得
        return self.data[index]

    def __len__(self):
        # データ数の取得
        return len(self.data)
"""

# パッケージの作成
package_name = "my_package"
package = package.Package(package_name)

# データセットのソースファイルを保存
package.save_source_file(
    package_name,
    "my_dataset.py",
    dataset_code
)

# パッケージの保存
package.save()

説明

この例では、MyDataset というデータセットのソースコードを my_dataset.py というファイル名で my_package というパッケージ内に保存します。

例 3: スクリプトのソースファイルを保存

import torch.package as package

# スクリプトのソースコード
script_code = """
import torch

def my_function(x):
    # 処理
    return x * 2
"""

# パッケージの作成
package_name = "my_package"
package = package.Package(package_name)

# スクリプトのソースファイルを保存
package.save_source_file(
    package_name,
    "my_script.py",
    script_code
)

# パッケージの保存
package.save()

説明

この例では、my_function というスクリプトのソースコードを my_script.py というファイル名で my_package というパッケージ内に保存します。



代替方法

  • 手動でソースファイルをコピーする
import os

# モデルのソースコード
model_code = """
import torch.nn as nn

class MyModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.linear = nn.Linear(10, 1)

    def forward(self, x):
        return self.linear(x)
"""

# パッケージのパス
package_dir = "my_package"

# モデルのソースファイルを保存
os.makedirs(package_dir, exist_ok=True)
with open(os.path.join(package_dir, "my_model.py"), "w") as f:
    f.write(model_code)

この方法は、単純ですが、ソースファイルの数が少ない場合や、ソースコードを直接編集したい場合に適しています。

  • zipfile モジュールを使用する
import zipfile

# モデルのソースコード
model_code = """
import torch.nn as nn

class MyModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.linear = nn.Linear(10, 1)

    def forward(self, x):
        return self.linear(x)
"""

# パッケージのパス
package_path = "my_package.zip"

# パッケージを作成
with zipfile.ZipFile(package_path, "w") as zip:
    # モデルのソースファイルをアーカイブに追加
    zip.writestr("my_model.py", model_code)

この方法は、複数のソースファイルを一度に保存したい場合や、圧縮したい場合に適しています。

  • torch.jit.save() を使用する
import torch
import torch.jit

# モデルの定義
class MyModel(torch.nn.Module):
    def __init__(self):
        super().__init__()
        self.linear = torch.nn.Linear(10, 1)

    def forward(self, x):
        return self.linear(x)

# モデルのトレース
model = MyModel()
x = torch.randn(1, 10)
model(x)

# モデルを保存
torch.jit.save(model, "my_model.pt")

この方法は、モデルのみを保存したい場合や、保存されたモデルをトーチスクリプトとして実行したい場合に適しています。

選択の指針

どの代替方法を選択するかは、以下の要素によって異なります。

  • 保存する対象
    モデルのみを保存したい場合は、torch.jit.save() を使用する必要があります。
  • 圧縮
    ソースファイルを圧縮したい場合は、zipfile モジュールを使用する必要があります。
  • ソースコードの編集
    ソースコードを直接編集したい場合は、手動でコピーするか、zipfile モジュールを使用する必要があります。
  • ソースファイルの数
    ソースファイルの数が少ない場合は、手動でコピーするのが最も簡単です。