Skip to content

Commit dd5df65

Browse files
larryliu0820malfet
authored andcommitted
Add build_native.sh and add README.md (#481)
* Add build_native.sh and add README.md Summary: Added a script to build C++ runner for ET and AOTI. Updated README.md to ask users to run it. Made some improvement on building speed, by reducing duplicate build command. Now we can rely on `install_requirements.sh` to install all of the C++ libraries needed for runner. Test Plan: Reviewers: Subscribers: Tasks: Tags: * Revert custom ops change Summary: Test Plan: Reviewers: Subscribers: Tasks: Tags: * Add build_native.sh to CI job Summary: Test Plan: Reviewers: Subscribers: Tasks: Tags: * Add README for building native runner for aoti Summary: Test Plan: Reviewers: Subscribers: Tasks: Tags:
1 parent e7cc602 commit dd5df65

File tree

7 files changed

+165
-50
lines changed

7 files changed

+165
-50
lines changed

.github/workflows/pull.yml

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ jobs:
246246
export REPO_NAME=${{ matrix.repo_name }}
247247
bash .ci/scripts/wget_checkpoint.sh ${REPO_NAME} ${{ matrix.resources }}
248248
echo "::endgroup::"
249-
249+
250250
echo "::group::Convert checkpoint"
251251
bash .ci/scripts/convert_checkpoint.sh ${REPO_NAME}
252252
echo "::endgroup::"
@@ -838,13 +838,11 @@ jobs:
838838
pip install -r requirements.txt
839839
840840
export TORCHCHAT_ROOT=${PWD}
841-
export ENABLE_ET_PYBIND=false
842-
./scripts/install_et.sh $ENABLE_ET_PYBIND
841+
bash scripts/build_native.sh et
843842
python3 -c 'import torch;print(f"torch: {torch.__version__, torch.version.git_version}")'
844843
python3 -c 'import torchvision;print(f"torchvision: {torchvision.__version__, torchvision.version.git_version}")'
845844
python3 -c 'import torchaudio;print(f"torchaudio: {torchaudio.__version__, torchaudio.version.git_version}")'
846-
cmake -S . -B ./cmake-out -DCMAKE_PREFIX_PATH=`python -c 'import torch;print(torch.utils.cmake_prefix_path)'` -G Ninja
847-
cmake --build ./cmake-out --target et_run
845+
848846
- name: Download checkpoints
849847
run: |
850848
@@ -891,8 +889,8 @@ jobs:
891889
pip install -r requirements.txt
892890
pip list
893891
894-
cmake -S . -B ./cmake-out -DCMAKE_PREFIX_PATH=`python -c 'import torch;print(torch.utils.cmake_prefix_path)'` -G Ninja
895-
cmake --build ./cmake-out --target aoti_run
892+
bash scripts/build_native.sh aoti
893+
896894
- name: Download checkpoint
897895
run: |
898896
mkdir -p checkpoints/stories15M

README.md

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,10 @@ with `python3 torchchat.py remove llama3`.
7373
* [Run exported .so file via your own C++ application](#run-server)
7474
* in Chat mode
7575
* in Generate mode
76-
* [Export for mobile via ExecuTorch](#export-executorch)
76+
* [Export for mobile via ExecuTorch](#exporting-for-mobile-via-executorch)
77+
* [Run exported ExecuTorch file on iOS or Android](#mobile-execution)
7778
* in Chat mode
7879
* in Generate mode
79-
* [Run exported ExecuTorch file on iOS or Android](#run-mobile)
80-
8180

8281
## Running via PyTorch / Python
8382

@@ -235,6 +234,20 @@ python3 torchchat.py generate --dso-path stories15M.so --prompt "Hello my name i
235234

236235
NOTE: The exported model will be large. We suggest you quantize the model, explained further down, before deploying the model on device.
237236

237+
**Build Native Runner Binary**
238+
239+
We provide an end-to-end C++ [runner](runner/run.cpp) that runs the `*.so` file exported after following the previous [examples](#aoti-aot-inductor) section. To build the runner binary on your Mac or Linux:
240+
241+
```bash
242+
scripts/build_native.sh aoti
243+
```
244+
245+
Run:
246+
247+
```bash
248+
cmake-out/aoti_run model.so -z tokenizer.model -i "Once upon a time"
249+
```
250+
238251
### ExecuTorch
239252

240253
ExecuTorch enables you to optimize your model for execution on a mobile or embedded device, but can also be used on desktop for testing.
@@ -250,7 +263,7 @@ python3 torchchat.py export stories15M --output-pte-path stories15M.pte
250263
python3 torchchat.py generate --device cpu --pte-path stories15M.pte --prompt "Hello my name is"
251264
```
252265

253-
See below under [Mobile Execution](#run-mobile) if you want to deploy and execute a model in your iOS or Android app.
266+
See below under [Mobile Execution](#mobile-execution) if you want to deploy and execute a model in your iOS or Android app.
254267

255268

256269

@@ -265,6 +278,20 @@ Read the [iOS documentation](docs/iOS.md) for more details on iOS.
265278

266279
Read the [Android documentation](docs/Android.md) for more details on Android.
267280

281+
**Build Native Runner Binary**
282+
283+
We provide an end-to-end C++ [runner](runner/run.cpp) that runs the `*.pte` file exported after following the previous [ExecuTorch](#executorch) section. Notice that this binary is for demo purpose, please follow the respective documentations, to see how to build a similar application on iOS and Android. To build the runner binary on your Mac or Linux:
284+
285+
```bash
286+
scripts/build_native.sh et
287+
```
288+
289+
Run:
290+
291+
```bash
292+
cmake-out/et_run model.pte -z tokenizer.model -i "Once upon a time"
293+
```
294+
268295
## Fine-tuned models from torchtune
269296

270297
torchchat supports running inference with models fine-tuned using [torchtune](https://github.com/pytorch/torchtune). To do so, we first need to convert the checkpoints into a format supported by torchchat.

runner/aoti.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ set(CMAKE_CXX_STANDARD 17)
33
IF(DEFINED ENV{TORCHCHAT_ROOT})
44
set(TORCHCHAT_ROOT $ENV{TORCHCHAT_ROOT})
55
ELSE()
6-
set(TORCHCHAT_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/..)
6+
set(TORCHCHAT_ROOT ${CMAKE_CURRENT_SOURCE_DIR})
77
ENDIF()
88

99
find_package(CUDA)

runner/et.cmake

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,27 @@ ELSE()
1515
set(CMAKE_OUT_DIR "cmake-out")
1616
ENDIF()
1717

18-
MESSAGE(STATUS "Using ET BUILD DIR: --[${ET_BUILD_DIR}]--")
19-
2018
IF(DEFINED ENV{TORCHCHAT_ROOT})
2119
set(TORCHCHAT_ROOT $ENV{TORCHCHAT_ROOT})
2220
ELSE()
23-
set(TORCHCHAT_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/..)
21+
set(TORCHCHAT_ROOT ${CMAKE_CURRENT_SOURCE_DIR})
2422
ENDIF()
2523

2624
project(Torchchat)
2725

26+
IF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
27+
SET(CMAKE_INSTALL_PREFIX ${TORCHCHAT_ROOT}/${ET_BUILD_DIR}/install CACHE PATH "Setting it to a default value" FORCE)
28+
ENDIF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
29+
2830
include(CMakePrintHelpers)
2931
include(runner/Utils.cmake)
3032

3133
cmake_print_variables(TORCHCHAT_ROOT)
3234

33-
MESSAGE(STATUS "Looking for excutorch in ${TORCHCHAT_ROOT}/${ET_BUILD_DIR}/install/lib/cmake/ExecuTorch")
34-
set(executorch_DIR ${TORCHCHAT_ROOT}/${ET_BUILD_DIR}/install/lib/cmake/ExecuTorch)
35-
find_package(executorch CONFIG PATHS ${executorch_DIR})
35+
MESSAGE(STATUS "Looking for excutorch in ${CMAKE_INSTALL_PREFIX}")
36+
37+
find_package(executorch CONFIG HINTS ${CMAKE_INSTALL_PREFIX})
38+
3639
if(executorch_FOUND)
3740
set(_common_include_directories ${TORCHCHAT_ROOT}/${ET_BUILD_DIR}/src)
3841

@@ -46,21 +49,21 @@ if(executorch_FOUND)
4649
# Link ET runtime + extensions
4750
target_link_libraries(
4851
et_run PRIVATE
49-
executorch
50-
extension_module
51-
${TORCHCHAT_ROOT}/${ET_BUILD_DIR}/src/executorch/${CMAKE_OUT_DIR}/extension/data_loader/libextension_data_loader.a # This one does not get installed by ExecuTorch
52-
optimized_kernels
53-
quantized_kernels
54-
portable_kernels
55-
cpublas
56-
eigen_blas
57-
# The libraries below need to be whole-archived linked
58-
optimized_native_cpu_ops_lib
59-
quantized_ops_lib
60-
xnnpack_backend
61-
XNNPACK
62-
pthreadpool
63-
cpuinfo
52+
executorch
53+
extension_module
54+
extension_data_loader
55+
optimized_kernels
56+
quantized_kernels
57+
portable_kernels
58+
cpublas
59+
eigen_blas
60+
# The libraries below need to be whole-archived linked
61+
optimized_native_cpu_ops_lib
62+
quantized_ops_lib
63+
xnnpack_backend
64+
XNNPACK
65+
pthreadpool
66+
cpuinfo
6467
)
6568
target_link_options_shared_lib(optimized_native_cpu_ops_lib)
6669
target_link_options_shared_lib(quantized_ops_lib)
@@ -73,8 +76,7 @@ if(executorch_FOUND)
7376
endif()
7477

7578
target_link_libraries(et_run PRIVATE
76-
"$<LINK_LIBRARY:WHOLE_ARCHIVE,${TORCHCHAT_ROOT}/${ET_BUILD_DIR}/src/executorch/${CMAKE_OUT_DIR}/examples/models/llama2/custom_ops/libcustom_ops.a>")
77-
79+
"$<LINK_LIBRARY:WHOLE_ARCHIVE,${TORCHCHAT_ROOT}/${ET_BUILD_DIR}/install/libcustom_ops.a>")
7880
# This one is needed for cpuinfo where it uses android specific log lib
7981
if(ANDROID)
8082
target_link_libraries(et_run PRIVATE log)

scripts/build_native.sh

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#!/bin/bash
2+
# Copyright (c) Meta Platforms, Inc. and affiliates.
3+
# All rights reserved.
4+
#
5+
# This source code is licensed under the BSD-style license found in the
6+
# LICENSE file in the root directory of this source tree.
7+
8+
# Simple script to build native aoti and et runner
9+
# Function to display a help message
10+
11+
set -ex
12+
13+
show_help() {
14+
cat << EOF
15+
Usage: ${0##*/} [-h|--help] aoti|et
16+
This script builds native aoti and et runner for LLM.
17+
-h|--help Display this help and exit
18+
aoti Build native runner for aoti
19+
et Build native runner for et
20+
EOF
21+
}
22+
# Check if no arguments were passed
23+
if [ $# -eq 0 ]; then
24+
echo "No arguments provided"
25+
show_help
26+
exit 1
27+
fi
28+
while (( "$#" )); do
29+
case "$1" in
30+
-h|--help)
31+
show_help
32+
exit 0
33+
;;
34+
aoti)
35+
echo "Building aoti native runner..."
36+
TARGET="aoti"
37+
shift
38+
;;
39+
et)
40+
echo "Building et native runner..."
41+
TARGET="et"
42+
shift
43+
;;
44+
*)
45+
echo "Invalid option: $1"
46+
show_help
47+
exit 1
48+
;;
49+
esac
50+
done
51+
52+
if [ -z "${TORCHCHAT_ROOT}" ]; then
53+
# Get the absolute path of the current script
54+
SCRIPT_PATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
55+
# Get the absolute path of the parent directory
56+
TORCHCHAT_ROOT="$(dirname "$SCRIPT_PATH")"
57+
fi
58+
59+
if [ -z "${ET_BUILD_DIR}" ]; then
60+
ET_BUILD_DIR="et-build"
61+
fi
62+
63+
source "$TORCHCHAT_ROOT/scripts/install_utils.sh"
64+
65+
if [[ "$TARGET" == "et" ]]; then
66+
pushd ${TORCHCHAT_ROOT}
67+
git submodule update --init
68+
find_cmake_prefix_path
69+
install_pip_dependencies
70+
clone_executorch
71+
install_executorch_libs false
72+
popd
73+
fi
74+
75+
# CMake commands
76+
cmake -S . -B ./cmake-out -DCMAKE_PREFIX_PATH=`python -c 'import torch;print(torch.utils.cmake_prefix_path)'` -G Ninja
77+
cmake --build ./cmake-out --target "${TARGET}"_run
78+
79+
printf "Build finished. Please run: \n./cmake-out model.<pte|so> -z tokenizer.model -i <prompt>"

scripts/install_et.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,5 @@ pushd ${TORCHCHAT_ROOT}
1919
find_cmake_prefix_path
2020
install_pip_dependencies
2121
clone_executorch
22-
install_executorch_python_libs $ENABLE_ET_PYBIND
23-
install_executorch
22+
install_executorch_libs $ENABLE_ET_PYBIND
2423
popd

scripts/install_utils.sh

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,7 @@ set -ex pipefail
99

1010
install_pip_dependencies() {
1111
echo "Intalling common pip packages"
12-
13-
pip3 install wheel
14-
pip3 install "cmake>=3.19"
15-
pip3 install ninja
16-
pip3 install zstd
12+
pip3 install wheel "cmake>=3.19" ninja zstd
1713
pushd ${TORCHCHAT_ROOT}
1814
pip3 install -r ./requirements.txt
1915
popd
@@ -60,6 +56,15 @@ install_executorch_python_libs() {
6056
popd
6157
}
6258

59+
COMMON_CMAKE_ARGS="\
60+
-DCMAKE_BUILD_TYPE=Release \
61+
-DEXECUTORCH_ENABLE_LOGGING=ON \
62+
-DEXECUTORCH_LOG_LEVEL=Info \
63+
-DEXECUTORCH_BUILD_OPTIMIZED=ON \
64+
-DEXECUTORCH_BUILD_EXTENSION_DATA_LOADER=ON \
65+
-DEXECUTORCH_BUILD_EXTENSION_MODULE=ON \
66+
-DEXECUTORCH_BUILD_QUANTIZED=ON"
67+
6368
install_executorch() {
6469
# AOT lib has to be build for model export
6570
# So by default it is built, and you can explicitly opt-out
@@ -96,20 +101,25 @@ install_executorch() {
96101
echo "Inside: ${PWD}"
97102
rm -rf ${CMAKE_OUT_DIR}
98103
mkdir ${CMAKE_OUT_DIR}
99-
cmake -DCMAKE_PREFIX_PATH=${MY_CMAKE_PREFIX_PATH} \
100-
-DCMAKE_BUILD_TYPE=Release \
101-
-DEXECUTORCH_ENABLE_LOGGING=ON \
102-
-DEXECUTORCH_LOG_LEVEL=Info \
104+
cmake ${COMMON_CMAKE_ARGS} \
105+
-DCMAKE_PREFIX_PATH=${MY_CMAKE_PREFIX_PATH} \
103106
-DEXECUTORCH_BUILD_CUSTOM_OPS_AOT=${EXECUTORCH_BUILD_CUSTOM_OPS_AOT_VAR} \
104107
-DEXECUTORCH_BUILD_CUSTOM=${EXECUTORCH_BUILD_CUSTOM_VAR} \
105-
-DEXECUTORCH_BUILD_OPTIMIZED=ON \
106-
-DEXECUTORCH_BUILD_EXTENSION_DATA_LOADER=ON \
107-
-DEXECUTORCH_BUILD_EXTENSION_MODULE=ON \
108108
-DEXECUTORCH_BUILD_XNNPACK=ON \
109-
-DEXECUTORCH_BUILD_QUANTIZED=ON \
110109
${CROSS_COMPILE_ARGS} \
111110
-S . -B ${CMAKE_OUT_DIR} -G Ninja
112111
cmake --build ${CMAKE_OUT_DIR}
113112
cmake --install ${CMAKE_OUT_DIR} --prefix ${TORCHCHAT_ROOT}/${ET_BUILD_DIR}/install
114113
popd
115114
}
115+
116+
install_executorch_libs() {
117+
# Install executorch python and C++ libs
118+
export CMAKE_ARGS="\
119+
${COMMON_CMAKE_ARGS} \
120+
-DCMAKE_PREFIX_PATH=${MY_CMAKE_PREFIX_PATH} \
121+
-DCMAKE_INSTALL_PREFIX=${TORCHCHAT_ROOT}/${ET_BUILD_DIR}/install"
122+
export CMAKE_BUILD_ARGS="--target install"
123+
124+
install_executorch_python_libs $1
125+
}

0 commit comments

Comments
 (0)