Skip to content
This repository was archived by the owner on Sep 10, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/pull.yml
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ jobs:
export REPO_NAME=${{ matrix.repo_name }}
bash .ci/scripts/wget_checkpoint.sh ${REPO_NAME} ${{ matrix.resources }}
echo "::endgroup::"

echo "::group::Convert checkpoint"
bash .ci/scripts/convert_checkpoint.sh ${REPO_NAME}
echo "::endgroup::"
Expand Down
21 changes: 17 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,10 @@ with `python3 torchchat.py remove llama3`.
* [Run exported .so file via your own C++ application](#run-server)
* in Chat mode
* in Generate mode
* [Export for mobile via ExecuTorch](#export-executorch)
* [Export for mobile via ExecuTorch](#exporting-for-mobile-via-executorch)
* [Run exported ExecuTorch file on iOS or Android](#mobile-execution)
* in Chat mode
* in Generate mode
* [Run exported ExecuTorch file on iOS or Android](#run-mobile)


## Running via PyTorch / Python

Expand Down Expand Up @@ -251,7 +250,7 @@ python3 torchchat.py export stories15M --output-pte-path stories15M.pte
python3 torchchat.py generate --device cpu --pte-path stories15M.pte --prompt "Hello my name is"
```

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


## Quantization
Expand All @@ -276,6 +275,20 @@ Read the [iOS documentation](docs/iOS.md) for more details on iOS.

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

**Build Native Runner Binary**

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:

```bash
scripts/build_native.sh et
```

Run:

```bash
cmake-out/et_run model.pte -z tokenizer.model -i "Once upon a time"
```

## Fine-tuned models from torchtune

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.
Expand Down
2 changes: 1 addition & 1 deletion runner/aoti.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ set(CMAKE_CXX_STANDARD 17)
IF(DEFINED ENV{TORCHCHAT_ROOT})
set(TORCHCHAT_ROOT $ENV{TORCHCHAT_ROOT})
ELSE()
set(TORCHCHAT_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/..)
set(TORCHCHAT_ROOT ${CMAKE_CURRENT_SOURCE_DIR})
ENDIF()

find_package(CUDA)
Expand Down
34 changes: 18 additions & 16 deletions runner/et.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,27 @@ ELSE()
set(CMAKE_OUT_DIR "cmake-out")
ENDIF()

MESSAGE(STATUS "Using ET BUILD DIR: --[${ET_BUILD_DIR}]--")

IF(DEFINED ENV{TORCHCHAT_ROOT})
set(TORCHCHAT_ROOT $ENV{TORCHCHAT_ROOT})
ELSE()
set(TORCHCHAT_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/..)
set(TORCHCHAT_ROOT ${CMAKE_CURRENT_SOURCE_DIR})
ENDIF()

project(Torchchat)

IF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
SET(CMAKE_INSTALL_PREFIX ${TORCHCHAT_ROOT}/${ET_BUILD_DIR}/install CACHE PATH "Setting it to a default value" FORCE)
ENDIF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)

include(CMakePrintHelpers)
include(runner/Utils.cmake)

cmake_print_variables(TORCHCHAT_ROOT)

MESSAGE(STATUS "Looking for excutorch in ${TORCHCHAT_ROOT}/${ET_BUILD_DIR}/install/lib/cmake/ExecuTorch")
set(executorch_DIR ${TORCHCHAT_ROOT}/${ET_BUILD_DIR}/install/lib/cmake/ExecuTorch)
find_package(executorch CONFIG PATHS ${executorch_DIR})
MESSAGE(STATUS "Looking for excutorch in ${CMAKE_INSTALL_PREFIX}")

find_package(executorch CONFIG HINTS ${CMAKE_INSTALL_PREFIX})

if(executorch_FOUND)
set(_common_include_directories ${TORCHCHAT_ROOT}/${ET_BUILD_DIR}/src)

Expand All @@ -46,35 +49,34 @@ if(executorch_FOUND)
# Link ET runtime + extensions
target_link_libraries(
et_run PRIVATE
cpublas
cpuinfo
eigen_blas
executorch
extension_data_loader
extension_module
${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
optimized_kernels
quantized_kernels
portable_kernels
cpublas
eigen_blas
pthreadpool
quantized_kernels
XNNPACK
# The libraries below need to be whole-archived linked
custom_ops
optimized_native_cpu_ops_lib
quantized_ops_lib
xnnpack_backend
XNNPACK
pthreadpool
cpuinfo
)
target_link_options_shared_lib(optimized_native_cpu_ops_lib)
target_link_options_shared_lib(quantized_ops_lib)
target_link_options_shared_lib(xnnpack_backend)
target_link_options_shared_lib(custom_ops)
# Not clear why linking executorch as whole-archive outside android/apple is leading
# to double registration. Most likely because of linkage issues.
# Will figure this out later. Until then use this.
if(ANDROID OR APPLE)
target_link_options_shared_lib(executorch)
endif()

target_link_libraries(et_run PRIVATE
"$<LINK_LIBRARY:WHOLE_ARCHIVE,${TORCHCHAT_ROOT}/${ET_BUILD_DIR}/src/executorch/${CMAKE_OUT_DIR}/examples/models/llama2/custom_ops/libcustom_ops.a>")

# This one is needed for cpuinfo where it uses android specific log lib
if(ANDROID)
target_link_libraries(et_run PRIVATE log)
Expand Down
79 changes: 79 additions & 0 deletions scripts/build_native.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#!/bin/bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.

# Simple script to build native aoti and et runner
# Function to display a help message

set -ex

show_help() {
cat << EOF
Usage: ${0##*/} [-h|--help] aoti|et
This script builds native aoti and et runner for LLM.
-h|--help Display this help and exit
aoti Build native runner for aoti
et Build native runner for et
EOF
}
# Check if no arguments were passed
if [ $# -eq 0 ]; then
echo "No arguments provided"
show_help
exit 1
fi
while (( "$#" )); do
case "$1" in
-h|--help)
show_help
exit 0
;;
aoti)
echo "Building aoti native runner..."
TARGET="aoti"
shift
;;
et)
echo "Building et native runner..."
TARGET="et"
shift
;;
*)
echo "Invalid option: $1"
show_help
exit 1
;;
esac
done

if [ -z "${TORCHCHAT_ROOT}" ]; then
# Get the absolute path of the current script
SCRIPT_PATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
# Get the absolute path of the parent directory
TORCHCHAT_ROOT="$(dirname "$SCRIPT_PATH")"
fi

if [ -z "${ET_BUILD_DIR}" ]; then
ET_BUILD_DIR="et-build"
fi

source "$TORCHCHAT_ROOT/scripts/install_utils.sh"

if [[ "$TARGET" == "et" ]]; then
pushd ${TORCHCHAT_ROOT}
git submodule update --init
find_cmake_prefix_path
install_pip_dependencies
clone_executorch
install_executorch_libs false
popd
fi

# CMake commands
cmake -S . -B ./cmake-out -DCMAKE_PREFIX_PATH=`python -c 'import torch;print(torch.utils.cmake_prefix_path)'` -G Ninja
cmake --build ./cmake-out --target "${TARGET}"_run

printf "Build finished. Please run: \n./cmake-out model.<pte|so> -z tokenizer.model -i <prompt>"
3 changes: 1 addition & 2 deletions scripts/install_et.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,5 @@ pushd ${TORCHCHAT_ROOT}
find_cmake_prefix_path
install_pip_dependencies
clone_executorch
install_executorch_python_libs $ENABLE_ET_PYBIND
install_executorch
install_executorch_libs $ENABLE_ET_PYBIND
popd
36 changes: 23 additions & 13 deletions scripts/install_utils.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,7 @@ set -ex pipefail

install_pip_dependencies() {
echo "Intalling common pip packages"

pip3 install wheel
pip3 install "cmake>=3.19"
pip3 install ninja
pip3 install zstd
pip3 install wheel "cmake>=3.19" ninja zstd
pushd ${TORCHCHAT_ROOT}
pip3 install -r ./requirements.txt
popd
Expand Down Expand Up @@ -60,6 +56,15 @@ install_executorch_python_libs() {
popd
}

COMMON_CMAKE_ARGS="\
-DCMAKE_BUILD_TYPE=Release \
-DEXECUTORCH_ENABLE_LOGGING=ON \
-DEXECUTORCH_LOG_LEVEL=Info \
-DEXECUTORCH_BUILD_OPTIMIZED=ON \
-DEXECUTORCH_BUILD_EXTENSION_DATA_LOADER=ON \
-DEXECUTORCH_BUILD_EXTENSION_MODULE=ON \
-DEXECUTORCH_BUILD_QUANTIZED=ON"

install_executorch() {
# AOT lib has to be build for model export
# So by default it is built, and you can explicitly opt-out
Expand Down Expand Up @@ -96,20 +101,25 @@ install_executorch() {
echo "Inside: ${PWD}"
rm -rf ${CMAKE_OUT_DIR}
mkdir ${CMAKE_OUT_DIR}
cmake -DCMAKE_PREFIX_PATH=${MY_CMAKE_PREFIX_PATH} \
-DCMAKE_BUILD_TYPE=Release \
-DEXECUTORCH_ENABLE_LOGGING=ON \
-DEXECUTORCH_LOG_LEVEL=Info \
cmake ${COMMON_CMAKE_ARGS} \
-DCMAKE_PREFIX_PATH=${MY_CMAKE_PREFIX_PATH} \
-DEXECUTORCH_BUILD_CUSTOM_OPS_AOT=${EXECUTORCH_BUILD_CUSTOM_OPS_AOT_VAR} \
-DEXECUTORCH_BUILD_CUSTOM=${EXECUTORCH_BUILD_CUSTOM_VAR} \
-DEXECUTORCH_BUILD_OPTIMIZED=ON \
-DEXECUTORCH_BUILD_EXTENSION_DATA_LOADER=ON \
-DEXECUTORCH_BUILD_EXTENSION_MODULE=ON \
-DEXECUTORCH_BUILD_XNNPACK=ON \
-DEXECUTORCH_BUILD_QUANTIZED=ON \
${CROSS_COMPILE_ARGS} \
-S . -B ${CMAKE_OUT_DIR} -G Ninja
cmake --build ${CMAKE_OUT_DIR}
cmake --install ${CMAKE_OUT_DIR} --prefix ${TORCHCHAT_ROOT}/${ET_BUILD_DIR}/install
popd
}

install_executorch_libs() {
# Install executorch python and C++ libs
export CMAKE_ARGS="\
${COMMON_CMAKE_ARGS} \
-DCMAKE_PREFIX_PATH=${MY_CMAKE_PREFIX_PATH} \
-DCMAKE_INSTALL_PREFIX=${TORCHCHAT_ROOT}/${ET_BUILD_DIR}/install"
export CMAKE_BUILD_ARGS="--target install"

install_executorch_python_libs $1
}