6

关于如何在M1上使用TorchSharp

 2 years ago
source link: https://zhen8838.github.io/2021/11/19/torchsharp/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

TorchSharp只有x64的,太蛋疼了,所以需要重新安装一遍.

1. 下载源码

git clone https://github.com/dotnet/TorchSharp.git --depth 1

2. 下载编译libtorch

git clone -b v1.10.0 --recurse-submodule https://github.com/pytorch/pytorch.git --depth 1
mkdir pytorch-build
cd pytorch-build
cmake -DBUILD_SHARED_LIBS:BOOL=ON -DCMAKE_BUILD_TYPE:STRING=Release -DPYTHON_EXECUTABLE:PATH=`which python3` -DCMAKE_INSTALL_PREFIX:PATH=../libtorch ../pytorch -G "Ninja"
cmake --build . --target install

注意这里默认是不开test的生成的.

3. 修改TorchSharp的编译命令

这里首先是修改libTrochSharp的cmake, 把llvm的路径改成本机的. 然后因为他默认要copy libtorch中的一些test的dylib到nupkg中,我之前编译的libtorch中没有test的输出, 这里需要注释掉. 最后就是把sdk版本改成net6.

diff --git a/Directory.Build.props b/Directory.Build.props
index 34f28ab..28b977e 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -92,7 +92,7 @@
<!-- By default only TorchSharp and no libtorch-cpu or libtorch-cuda packages are built. The CI file controls these via 'BuildLibTorchPackages' -->
<!-- This then selectively turns these on over several CI jobs since different pacakges are done in different jobs -->
<IncludeTorchSharpPackage>true</IncludeTorchSharpPackage>
- <IncludeLibTorchCpuPackages>false</IncludeLibTorchCpuPackages>
+ <IncludeLibTorchCpuPackages>true</IncludeLibTorchCpuPackages>
<IncludeLibTorchCudaPackages>false</IncludeLibTorchCudaPackages>
</PropertyGroup>

diff --git a/Directory.Build.targets b/Directory.Build.targets
index b79d260..3383de5 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -68,18 +68,18 @@
<ItemGroup Condition="'$(NativeTargetArchitecture)' == 'x64'and $([MSBuild]::IsOSPlatform('osx')) and '$(TestUsesLibTorch)' == 'true' and '$(SkipNative)' != 'true' ">
<NativeAssemblyReference Include="c10" />
<NativeAssemblyReference Include="caffe2_detectron_ops" />
- <NativeAssemblyReference Include="caffe2_module_test_dynamic" />
+ <!-- <NativeAssemblyReference Include="caffe2_module_test_dynamic" /> -->
<NativeAssemblyReference Include="caffe2_observers" />
- <NativeAssemblyReference Include="fbjni" />
- <NativeAssemblyReference Include="iomp5" />
- <NativeAssemblyReference Include="jitbackend_test" />
- <NativeAssemblyReference Include="pytorch_jni" />
+ <!-- <NativeAssemblyReference Include="fbjni" /> -->
+ <!-- <NativeAssemblyReference Include="iomp5" /> -->
+ <!-- <NativeAssemblyReference Include="jitbackend_test" /> -->
+ <!-- <NativeAssemblyReference Include="pytorch_jni" /> -->
<NativeAssemblyReference Include="shm" />
<NativeAssemblyReference Include="torch" />
<NativeAssemblyReference Include="torch_cpu" />
<NativeAssemblyReference Include="torch_global_deps" />
<NativeAssemblyReference Include="torch_python" />
- <NativeAssemblyReference Include="torchbind_test" />
+ <!-- <NativeAssemblyReference Include="torchbind_test" /> -->
</ItemGroup>

<!-- Linux CPU libtorch binary list used for examples and testing -->
diff --git a/global.json b/global.json
index 058794f..15f9eb4 100644
--- a/global.json
+++ b/global.json
@@ -1,6 +1,6 @@
{
"sdk": {
- "version": "5.0.402",
+ "version": "6.0.100",
"allowPrerelease": true,
"rollForward": "minor"
}
diff --git a/src/Native/LibTorchSharp/CMakeLists.txt b/src/Native/LibTorchSharp/CMakeLists.txt
index 46b5c32..b1828cc 100644
--- a/src/Native/LibTorchSharp/CMakeLists.txt
+++ b/src/Native/LibTorchSharp/CMakeLists.txt
@@ -1,8 +1,8 @@
project(LibTorchSharp)

if(APPLE)
- include_directories("/usr/local/include" "/usr/local/opt/llvm/include")
- link_directories("/usr/local/lib" "/usr/local/opt/llvm/lib")
+ include_directories("/Users/lisa/Documents/llvm-project/build/install/include")
+ link_directories("/Users/lisa/Documents/llvm-project/build/install/lib")
endif()
find_package(Torch REQUIRED PATHS ${LIBTORCH_PATH})

diff --git a/src/Redist/libtorch-cpu/libtorch-cpu.proj b/src/Redist/libtorch-cpu/libtorch-cpu.proj
index 4240fe1..3eeeabe 100644
--- a/src/Redist/libtorch-cpu/libtorch-cpu.proj
+++ b/src/Redist/libtorch-cpu/libtorch-cpu.proj
@@ -41,21 +41,21 @@
<File Include="libtorch\lib\uv.dll" />
</ItemGroup>
<ItemGroup Condition="'$(TargetOS)' == 'mac'">
- <File Include="libtorch\lib\libbackend_with_compiler.dylib" />
+ <!-- <File Include="libtorch\lib\libbackend_with_compiler.dylib" /> -->
<File Include="libtorch\lib\libc10.dylib" />
<File Include="libtorch\lib\libcaffe2_detectron_ops.dylib" />
- <File Include="libtorch\lib\libcaffe2_module_test_dynamic.dylib" />
+ <!-- <File Include="libtorch\lib\libcaffe2_module_test_dynamic.dylib" /> -->
<File Include="libtorch\lib\libcaffe2_observers.dylib" />
- <File Include="libtorch\lib\libfbjni.dylib" />
- <File Include="libtorch\lib\libiomp5.dylib" />
- <File Include="libtorch\lib\libjitbackend_test.dylib" />
- <File Include="libtorch\lib\libpytorch_jni.dylib" />
+ <!-- <File Include="libtorch\lib\libfbjni.dylib" /> -->
+ <!-- <File Include="libtorch\lib\libiomp5.dylib" /> -->
+ <!-- <File Include="libtorch\lib\libjitbackend_test.dylib" /> -->
+ <!-- <File Include="libtorch\lib\libpytorch_jni.dylib" /> -->
<File Include="libtorch\lib\libshm.dylib" />
<File Include="libtorch\lib\libtorch.dylib" />
<File Include="libtorch\lib\libtorch_cpu.dylib" />
<File Include="libtorch\lib\libtorch_global_deps.dylib" />
<File Include="libtorch\lib\libtorch_python.dylib" />
- <File Include="libtorch\lib\libtorchbind_test.dylib" />
+ <!-- <File Include="libtorch\lib\libtorchbind_test.dylib" /> -->
</ItemGroup>
<ItemGroup Condition="'$(TargetOS)' == 'linux'">
<File Include="libtorch\lib\libbackend_with_compiler.so" />

4. 开始打包

执行dotnet pack --configuration release,注意他这里会自动下载libtorch的release包,但是修改他的下载的脚本又着实麻烦.所以我们要等到他下载好开始编译Native的时候按ctrl+c先中断,然后把我们的libtorch替换他解压出来的libtorch

cd bin/obj/AnyCPU.Release/libtorch-cpu/libtorch-macos-1.10.0cpu/
rm -rf libtorch
cp -r ~/Documents/libtorch .

然后再执行dotnet pack --configuration release最后打包出来.

5. 配置nuget配置

我们要把编译生成的路径作为nuget的一个源,同时为了避免冲突还得关闭原来的源, 所以在项目路径下添加NuGet.Config文件

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
<add key="m1" value="/Users/lisa/Documents/TorchSharp/bin/packages/Release" />
</packageSources>
<activePackageSource>
<add key="m1" value="/Users/lisa/Documents/TorchSharp/bin/packages/Release" />
</activePackageSource>
<disabledPackageSources>
<add key="nuget.org" value="true" />
</disabledPackageSources>
</configuration>

6. 编译项目

执行dotnet build -v:d > log, 我这里在log 文件中就可以看到如下内容

正在将文件从“/Users/lisa/.nuget/packages/libtorch-cpu-osx-x64/1.10.0.1/runtimes/osx-x64/native/libcaffe2_observers.dylib”复制到“/Users/lisa/Documents/nncase/bin/Nncase.Tests/net6.0/runtimes/osx-x64/native/libcaffe2_observers.dylib”。
正在将文件从“/Users/lisa/.nuget/packages/libtorch-cpu-osx-x64/1.10.0.1/runtimes/osx-x64/native/libcaffe2_detectron_ops.dylib”复制到“/Users/lisa/Documents/nncase/bin/Nncase.Tests/net6.0/runtimes/osx-x64/native/libcaffe2_detectron_ops.dylib”。
正在将文件从“/Users/lisa/.nuget/packages/libtorch-cpu-osx-x64/1.10.0.1/runtimes/osx-x64/native/libc10.dylib”复制到“/Users/lisa/Documents/nncase/bin/Nncase.Tests/net6.0/runtimes/osx-x64/native/libc10.dylib”。

我们检查dylib的格式, 如果是arm64就说明是ok的. 如果还是x86的话, 是因为替换libtorch的时机晚了,他是在src/Redist/libtorch-cpu/libtorch-cpu.projCopyFilesFromArchive执行的.

❯ file /Users/lisa/Documents/nncase/bin/Nncase.Tests/net6.0/runtimes/osx-x64/native/libcaffe2_observers.dylib
/Users/lisa/Documents/nncase/bin/Nncase.Tests/net6.0/runtimes/osx-x64/native/libcaffe2_observers.dylib: Mach-O 64-bit dynamically linked shared library arm64

7. 修复路径问题

这里还是有个问题, 那就是TorchSharp默认会从TorchSharp.dll的路径加载libtorch.dylib,但是我生成出来的包,默认是把libtorch.dylib放到net6.0/runtimes/osx-x64/native路径下,导致默认找不到这个libtorch. 手动解决到也简单

cd bin/Nncase.Tests/net6.0/
mv runtimes/osx-x64/native/* .

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK