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 설정되지 않으면 빌드 스크립트는 download-libtorch 기능을 사용하여 미리 구축 된 이진 버전의 Libtorch를 다운로드 할 수 있습니다. 기본적으로 CPU 버전이 사용됩니다. TORCH_CUDA_VERSION 환경 변수는 CUDA 11.7을 사용하여 사전 구축 된 이진을 얻기 위해 cu117 로 설정할 수 있습니다. Linux 플랫폼에서 빌드 스크립트는 /usr/lib/libtorch.so 의 시스템 전체 Libtorch 라이브러리를 찾습니다.
LIBTORCH_USE_PYTORCH 환경 변수가 설정되면 활성 Python 통역사를 호출하여 Torch 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 Path 변수에 추가하십시오.일시적으로 환경 변수를 설정하는 것을 선호하는 경우 PowerShell에서는 실행할 수 있습니다.
$ Env: LIBTORCH = " X:pathtolibtorch "
$ Env: Path += " ;X:pathtolibtorchlib "cargo run --example basics 과 같은 몇 가지 예제를 실행할 수 있어야합니다.Pytorch 문서에 따라 Windows 디버그 및 릴리스 빌드는 적합하지 않습니다. Libtorch의 잘못된 버전이 사용되는 경우 일부 segfaults로 이어질 수 있습니다.
Pytorch가 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 초기 값이 0 인 두 개의 변수 x1 과 x2 사용합니다. 텐서 xs 에 적용되는 전방 패스는 xs * x1 + exp(xs) * x2 반환합니다.
모델이 생성되면 nn::Sgd Optimizer가 생성됩니다. 그런 다음 훈련 루프의 각 단계에서 :
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는 신경망 아키텍처를 만드는 데 사용될 수 있습니다. 예를 들어 다음 코드는 하나의 숨겨진 계층으로 간단한 모델을 정의하고 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 구현에서 추출한 가중치는 여기에서 resnet18.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 텐서를 저장하기위한 포옹으로 새로운 간단한 형식입니다. 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 훈련 된 모델에 대한 웹캠 피드에서 추론을 실행합니다. 이 스레드의 몇 가지 세부 사항을 참조하십시오.
이 문제를 확인하십시오.
이 문제를 참조하십시오. 이것은 Rust-Analyzer가 LIBTORCH 및 LD_LIBRARY_PATH 와 같은 적절한 환경 변수에 대해 알지 못하면 발생할 수 있습니다.
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 ). /path/to/libtorch 가 libtorch 설치의 경로 인 .bashrc 에 다음을 추가 할 수 있습니다.
# 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를 참조하십시오.