PytorchのC ++ APIの錆バインディング。 tchクレートの目標は、C ++ Pytorch API(別名Libtorch)の周りにいくつかの薄いラッパーを提供することです。これは、元のC ++ APIにできるだけ近くにとどまることを目指しています。これに加えて、より慣用的な錆びたバインディングを開発することができます。ドキュメントはdocs.Rsにあります。
Changelog
Libtorchの上にあるC APIのコード生成部分は、OCAML-TORCHから来ています。
このクレートでは、バージョンV2.5.1のC ++ Pytorchライブラリ(Libtorch)をシステムで利用できるようにする必要があります。どちらもできます:
LIBTORCH Environment変数を介してビルドスクリプトにそれを知らせます。LIBTORCH_USE_PYTORCH=1実行します。LIBTORCHが設定されていない場合、Build Scriptは、 download-libtorch機能を使用して、事前に構築されたバイナリバージョンのLibtorchをダウンロードできます。デフォルトでは、CPUバージョンが使用されています。 TORCH_CUDA_VERSION環境変数は、CUDA 11.7を使用して事前に構築されたバイナリを取得するためにcu117に設定できます。 Linuxプラットフォームでは、ビルドスクリプトでは、 /usr/lib/libtorch.so /libtorch.soのシステム全体のLibtorchライブラリを探します。
LIBTORCH_USE_PYTORCH環境変数が設定されている場合、アクティブなPythonインタープリターが呼び出され、トーチPythonパッケージに関する情報を取得します。このバージョンはリンクされます。
libtorchを入手し、zipファイルのコンテンツを抽出します。.bashrcまたは等価物に次のものを追加します。ここで、 /path/to/libtorchファイルを解凍するときに作成されたディレクトリへのパスです。 export LIBTORCH=/path/to/libtorchヘッダーファイルの場所は、以下を介して共有ライブラリとは別に指定することもできます。
# LIBTORCH_INCLUDE must contain `include` directory.
export LIBTORCH_INCLUDE=/path/to/libtorch/
# LIBTORCH_LIB must contain `lib` directory.
export LIBTORCH_LIB=/path/to/libtorch/ Windowsユーザーの場合、 X:pathtolibtorchが解凍されたLibtorchディレクトリであると仮定します。
LIBTORCH変数を作成し、 X:pathtolibtorchに設定します。X:pathtolibtorchlib to the Path変数。一時的に環境変数を設定することを好む場合は、PowerShellで実行できます
$ Env: LIBTORCH = " X:pathtolibtorch "
$ Env: Path += " ;X:pathtolibtorchlib "cargo run --example basicsできるようになりました。Pytorchドキュメントによると、WindowsデバッグとリリースビルドはABI互換ではありません。これにより、Libtorchの誤ったバージョンが使用されている場合、一部のセグフォールトにつながる可能性があります。
PytorchにはMingwとの互換性の問題があるため、Mingwベースのものではなく、MINGWベースのものではなく、MSVC Rust Toolchain(例えば、Rustupを介してstable-x86_64-pc-windows-msvcインストールすることにより)を使用することをお勧めします。
環境変数LIBTORCH_STATIC=1設定する場合、 libtorch動的ライブラリを使用するのではなく、静的にリンクされています。事前にコンパイルされたアーティファクトには、デフォルトではlibtorch.aが含まれていないようであるため、これは手動でコンパイルする必要があります。
git clone -b v2.5.1 --recurse-submodule https://github.com/pytorch/pytorch.git pytorch-static --depth 1
cd pytorch-static
USE_CUDA=OFF BUILD_SHARED_LIBS=OFF python setup.py build
# export LIBTORCH to point at the build directory in pytorch-static. このクレートは、Pytorchテンソルをラップするテンソルタイプを提供します。テンソル操作を実行する方法の最小限の例を以下に示します。
use tch :: Tensor ;
fn main ( ) {
let t = Tensor :: from_slice ( & [ 3 , 1 , 4 , 1 , 5 ] ) ;
let t = t * 2 ;
t . print ( ) ;
}Pytorchは、サポートするほとんどのテンソル操作に自動差別化を提供します。これは、勾配降下を使用してモデルをトレーニングするために一般的に使用されます。最適化は、形状と初期化を定義することにより、 nn::VarStoreを介して作成される変数に対して実行されます。
以下の例では、 my_module 2つの変数x1とx2を使用します。これは初期値が0です。テンソルxsに適用されるフォワードパスはxs * x1 + exp(xs) * x2を返します。
モデルが生成されると、 nn::Sgdオプティマイザーが作成されます。次に、トレーニングループの各ステップで:
VarStoreの変数がそれに応じて変更されます。 use tch :: nn :: { Module , OptimizerConfig } ;
use tch :: { kind , nn , Device , Tensor } ;
fn my_module ( p : nn :: Path , dim : i64 ) -> impl nn :: Module {
let x1 = p . zeros ( "x1" , & [ dim ] ) ;
let x2 = p . zeros ( "x2" , & [ dim ] ) ;
nn :: func ( move |xs| xs * & x1 + xs . exp ( ) * & x2 )
}
fn gradient_descent ( ) {
let vs = nn :: VarStore :: new ( Device :: Cpu ) ;
let my_module = my_module ( vs . root ( ) , 7 ) ;
let mut opt = nn :: Sgd :: default ( ) . build ( & vs , 1e-2 ) . unwrap ( ) ;
for _idx in 1 .. 50 {
// Dummy mini-batches made of zeros.
let xs = Tensor :: zeros ( & [ 7 ] , kind :: FLOAT_CPU ) ;
let ys = Tensor :: zeros ( & [ 7 ] , kind :: FLOAT_CPU ) ;
let loss = ( my_module . forward ( & xs ) - ys ) . pow_tensor_scalar ( 2 ) . sum ( kind :: Kind :: Float ) ;
opt . backward_step ( & loss ) ;
}
}nn APIを使用してニューラルネットワークアーキテクチャを作成できます。たとえば、次のコードは、1つの隠れレイヤーを使用した単純なモデルを定義し、Adam Optimizerを使用してMnistデータセットでトレーニングします。
use anyhow :: Result ;
use tch :: { nn , nn :: Module , nn :: OptimizerConfig , Device } ;
const IMAGE_DIM : i64 = 784 ;
const HIDDEN_NODES : i64 = 128 ;
const LABELS : i64 = 10 ;
fn net ( vs : & nn :: Path ) -> impl Module {
nn :: seq ( )
. add ( nn :: linear (
vs / "layer1" ,
IMAGE_DIM ,
HIDDEN_NODES ,
Default :: default ( ) ,
) )
. add_fn ( |xs| xs . relu ( ) )
. add ( nn :: linear ( vs , HIDDEN_NODES , LABELS , Default :: default ( ) ) )
}
pub fn run ( ) -> Result < ( ) > {
let m = tch :: vision :: mnist :: load_dir ( "data" ) ? ;
let vs = nn :: VarStore :: new ( Device :: Cpu ) ;
let net = net ( & vs . root ( ) ) ;
let mut opt = nn :: Adam :: default ( ) . build ( & vs , 1e-3 ) ? ;
for epoch in 1 .. 200 {
let loss = net
. forward ( & m . train_images )
. cross_entropy_for_logits ( & m . train_labels ) ;
opt . backward_step ( & loss ) ;
let test_accuracy = net
. forward ( & m . test_images )
. accuracy_for_logits ( & m . test_labels ) ;
println ! (
"epoch: {:4} train loss: {:8.5} test acc: {:5.2}%" ,
epoch ,
f64 :: from ( & loss ) ,
100. * f64 :: from ( & test_accuracy ) ,
) ;
}
Ok ( ( ) )
}トレーニングループの詳細については、詳細なチュートリアルをご覧ください。
前処理されたモデルの例は、画像で事前に訓練されたコンピュータービジョンモデルを使用する方法を示しています。 Pytorchの実装から抽出された重みは、ここからダウンロードできます。
その例は、次のコマンドで実行できます。
cargo run --example pretrained-models -- resnet18.ot tiger.jpgこれにより、画像の上位5つのImagenetカテゴリを印刷する必要があります。この例のコードは非常に簡単です。
// First the image is loaded and resized to 224x224.
let image = imagenet :: load_image_and_resize ( image_file ) ? ;
// A variable store is created to hold the model parameters.
let vs = tch :: nn :: VarStore :: new ( tch :: Device :: Cpu ) ;
// Then the model is built on this variable store, and the weights are loaded.
let resnet18 = tch :: vision :: resnet :: resnet18 ( vs . root ( ) , imagenet :: CLASS_COUNT ) ;
vs . load ( weight_file ) ? ;
// Apply the forward pass of the model to get the logits and convert them
// to probabilities via a softmax.
let output = resnet18
. forward_t ( & image . unsqueeze ( 0 ) , /*train=*/ false )
. softmax ( - 1 ) ;
// Finally print the top 5 categories and their associated probabilities.
for ( probability , class ) in imagenet :: top ( & output , 5 ) . iter ( ) {
println ! ( "{:50} {:5.2}%" , class , 100.0 * probability )
}safetensors 、テンソルを保存するためのHuggingfaceによる新しいシンプルな形式です。 Pythonのpickleモジュールに依存していないため、テンソルは特定のクラスとモデルが保存されたときに使用される正確なディレクトリ構造に拘束されません。また、ゼロコピーです。つまり、ファイルを読むには、元のファイルよりもメモリ以上のものが必要ありません。
safetensorsの詳細については、https://github.com/huggingface/safetensorsをご覧ください
safetensorsのインストールPIPマネージャーを介してsafetensorsをインストールできます。
pip install safetensors
import torchvision
from safetensors import torch as stt
model = torchvision . models . resnet18 ( pretrained = True )
stt . save_file ( model . state_dict (), 'resnet18.safetensors' )注:エクスポートのファイル名は、 tchによって適切にデコードされるために、 .safetensorsサフィックスに命名する必要があります。
tchで重量をインポートします use anyhow :: Result ;
use tch :: {
Device ,
Kind ,
nn :: VarStore ,
vision :: {
imagenet ,
resnet :: resnet18 ,
}
} ;
fn main ( ) -> Result < ( ) > {
// Create the model and load the pre-trained weights
let mut vs = VarStore :: new ( Device :: cuda_if_available ( ) ) ;
let model = resnet18 ( & vs . root ( ) , 1000 ) ;
vs . load ( "resnet18.safetensors" ) ? ;
// Load the image file and resize it to the usual imagenet dimension of 224x224.
let image = imagenet :: load_image_and_resize224 ( "dog.jpg" ) ?
. to_device ( vs . device ( ) ) ;
// Apply the forward pass of the model to get the logits
let output = image
. unsqueeze ( 0 )
. apply_t ( & model , false )
. softmax ( - 1 , Kind :: Float ) ;
// Print the top 5 categories for this image.
for ( probability , class ) in imagenet :: top ( & output , 5 ) . iter ( ) {
println ! ( "{:50} {:5.2}%" , class , 100.0 * probability )
}
Ok ( ( ) )
}さらなる例は次のとおりです。
外部素材:
tch-rsとopencvを使用して、MobiLenet V3に基づくPythonトレーニングモデルのWebカメラフィードで推論を実行します。 このスレッドの詳細をご覧ください。
この問題を確認してください。
この問題を参照してください。これは、 LIBTORCHやLD_LIBRARY_PATHなどの適切な環境変数を知らないRust-analyzerによって引き起こされる可能性があります。
Pyo3を介してPythonからRust/TCHコードを呼び出すことができます。TCH-EXTは、このようなPython拡張の例を提供します。
生成されたバイナリを実行するときに共有ライブラリを見つけられないというエラーが発生した場合(例: error while loading shared libraries: libtorch_cpu.so: cannot open shared object file: No such file or directory )。 .bashrcに次のように追加してください。ここで/path/to/libtorch Libtorchインストールへのパスです。
# For Linux
export LD_LIBRARY_PATH=/path/to/libtorch/lib:$LD_LIBRARY_PATH
# For macOS
export DYLD_LIBRARY_PATH=/path/to/libtorch/lib:$DYLD_LIBRARY_PATH
tch-rs 、オプションでMITライセンスとApacheライセンス(バージョン2.0)の両方の条件の下で配布されます。
詳細については、ライセンスAPache、ライセンスマイットを参照してください。