Привязок ржавчины для API C ++ Pytorch. Целью ящика tch является предоставление некоторых тонких оберток вокруг API C ++ Pytorch (он же Libtorch). Он направлен на то, чтобы оставаться как можно ближе к исходному API C ++. Помимо этого можно было разработать больше идиоматических привязков ржавчины. Документацию можно найти на Docs.rs.
изменение
Часть генерации кода для C API на вершине Libtorch поступает из Ocaml-Torch.
Этот ящик требует, чтобы библиотека C ++ Pytorch (Libtorch) в версии V2.5.1 для вашей системы была доступна. Вы можете либо:
LIBTORCH .LIBTORCH_USE_PYTORCH=1 .LIBTORCH не установлен, сценарий сборки может загрузить предварительно построенную двоичную версию Libtorch, используя функцию download-libtorch . По умолчанию используется версия процессора. Переменная среды TORCH_CUDA_VERSION может быть установлена на cu117 , чтобы получить предварительно построенный двоичный файл с использованием CUDA 11.7. На платформах Linux сценарий сборки будет искать общеобразовательную библиотеку Libtrch в /usr/lib/libtorch.so .
Если установлена переменная среды LIBTORCH_USE_PYTORCH , активный интерпретатор Python вызывается для получения информации о пакете Torch Python. Эта версия затем связана с.
libtorch из разделения загрузки веб -сайта Pytorch и извлеките содержание файла 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 к переменной Path .Если вы предпочитаете временно установить переменные среды, в PowerShell вы можете запустить
$ Env: LIBTORCH = " X:pathtolibtorch "
$ Env: Path += " ;X:pathtolibtorchlib "cargo run --example basics .Согласно документам Pytorch, сборки отладки и выпуска Windows не совместимы с ABI. Это может привести к некоторым сегфаултам, если используется неверная версия Libtorch.
Рекомендуется использовать инструмент инструмента MSVC Rust (например, установив stable-x86_64-pc-windows-msvc через Rustup), а не на основе Mingw, поскольку Pytorch имеет проблемы с совместимостью с Mingw.
При установке переменной среды 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 использует две переменные x1 и x2 , которые исходные значения являются 0. Правный проход, применяемый к Tensor 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 может использоваться для создания архитектур нейронной сети, например, следующий код определяет простую модель с одним скрытым слоем и обучает ее в наборе данных MNIST с помощью оптимизатора ADAM.
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, могут быть загружены здесь Resnet18.OT и здесь Resnet34.OT.
Затем пример можно запустить по следующей команде:
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 для хранения тензоров. Он не полагается на модуль pickle Python, и поэтому тензоры не связаны с конкретными классами и точной структурой каталога, используемой при сохранении модели. Это также нулевая копия, что означает, что чтение файла потребует не больше памяти, чем исходный файл.
Для получения дополнительной информации о safetensors , пожалуйста, ознакомьтесь с https://github.com/huggingface/safetensors
safetensors Вы можете установить safetensors через PIP Manager:
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' ) Примечание. Имя файла экспорта должно быть названо с суффиксом .safetensors , чтобы он был должным образом декодирован tch .
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 для выполнения вывода на веб-камере для некоторой обученной модели Python на основе Mobilenet V3. Смотрите некоторые детали в этой теме.
Проверьте эту проблему.
Посмотрите на эту проблему, это может быть вызвано тем, что анализер ржавчина не знает о соответствующих переменных окружающей среды, таких как LIBTORCH и LD_LIBRARY_PATH .
Можно вызвать код Rust/TCH из Python через PYO3, 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), по вашему варианту.
Смотрите лицензию-апоше, лицензионная MIT для получения более подробной информации.