Skip to content

Commit de9c414

Browse files
larryliu0820malfet
authored andcommitted
Add support for tiktoken and refactored runner structure (#435)
* Add support for tiktoken and refactored runner structure Summary: Unified runner and move runner-et/CMakeLists.txt to runner/et.cmake and runner-aoti/CMakeLists.txt to runner/aoti.cmake. Added a root level CMakeLists.txt to build a tokenizer library and link to both targets separately. In CLI we need to specify the target to run: ``` cmake --build ./cmake-out --target et_run/aoti_run ``` Test Plan: Reviewers: Subscribers: Tasks: Tags: * Fix CI Summary: Test Plan: Reviewers: Subscribers: Tasks: Tags: * Fix more CI Summary: Test Plan: Reviewers: Subscribers: Tasks: Tags: * Further fix CI Summary: Test Plan: Reviewers: Subscribers: Tasks: Tags: * Lint` Summary: Test Plan: Reviewers: Subscribers: Tasks: Tags: * Update build_android.sh Summary: Test Plan: Reviewers: Subscribers: Tasks: Tags: * Rebase Summary: Test Plan: Reviewers: Subscribers: Tasks: Tags: * Fix cmake commands in CI job Summary: Test Plan: Reviewers: Subscribers: Tasks: Tags:
1 parent 0b4b56a commit de9c414

File tree

21 files changed

+788
-145
lines changed

21 files changed

+788
-145
lines changed

.github/workflows/pull.yml

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -714,7 +714,9 @@ jobs:
714714
runs-on: ${{matrix.runner}}
715715
steps:
716716
- name: Checkout repo
717-
uses: actions/checkout@v2
717+
uses: actions/checkout@v3
718+
with:
719+
submodules: true
718720
- name: Setup Python
719721
uses: actions/setup-python@v2
720722
with:
@@ -737,8 +739,8 @@ jobs:
737739
python3 -c 'import torch;print(f"torch: {torch.__version__, torch.version.git_version}")'
738740
python3 -c 'import torchvision;print(f"torchvision: {torchvision.__version__, torchvision.version.git_version}")'
739741
python3 -c 'import torchaudio;print(f"torchaudio: {torchaudio.__version__, torchaudio.version.git_version}")'
740-
cmake -S ./runner-et -B ./runner-et/cmake-out -G Ninja
741-
cmake --build ./runner-et/cmake-out
742+
cmake -S . -B ./cmake-out -DCMAKE_PREFIX_PATH=`python -c 'import torch;print(torch.utils.cmake_prefix_path)'` -G Ninja
743+
cmake --build ./cmake-out --target et_run
742744
- name: Download checkpoints
743745
run: |
744746
@@ -753,7 +755,7 @@ jobs:
753755
cat ./output_eager
754756
755757
python torchchat.py export stories15M --output-pte-path ./model.pte
756-
./runner-et/cmake-out/run ./model.pte -z ./tokenizer.bin -t 0 -i "${PRMT}" > ./output_et
758+
./cmake-out/et_run ./model.pte -z ./tokenizer.bin -t 0 -i "${PRMT}" > ./output_et
757759
cat ./output_et
758760
759761
echo "Tests complete."
@@ -770,6 +772,8 @@ jobs:
770772
steps:
771773
- name: Checkout repo
772774
uses: actions/checkout@v3
775+
with:
776+
submodules: true
773777
- name: Setup Python
774778
uses: actions/setup-python@v4
775779
with:
@@ -783,10 +787,8 @@ jobs:
783787
pip install -r requirements.txt
784788
pip list
785789
786-
cd ${TORCHCHAT_ROOT}/runner-aoti
787-
cmake -Bbuild -DCMAKE_PREFIX_PATH=`python -c 'import torch;print(torch.utils.cmake_prefix_path)'`
788-
cmake --build build
789-
cd ..
790+
cmake -S . -B ./cmake-out -DCMAKE_PREFIX_PATH=`python -c 'import torch;print(torch.utils.cmake_prefix_path)'` -G Ninja
791+
cmake --build ./cmake-out --target aoti_run
790792
- name: Download checkpoint
791793
run: |
792794
mkdir -p checkpoints/stories15M
@@ -807,7 +809,7 @@ jobs:
807809
808810
python torchchat.py export --checkpoint-path ${MODEL_DIR}/stories15M.pt --output-dso-path /tmp/model.so
809811
810-
./runner-aoti/build/run /tmp/model.so -z ${MODEL_DIR}/tokenizer.bin -i "${PROMPT}" > ${PWD}/output_aoti
812+
./cmake-out/aoti_run /tmp/model.so -z ${MODEL_DIR}/tokenizer.bin -i "${PROMPT}" > ${PWD}/output_aoti
811813
cat ${PWD}/output_aoti
812814
813815
echo "Tests complete."

.gitmodules

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[submodule "tokenizer/third-party/abseil-cpp"]
2+
path = tokenizer/third-party/abseil-cpp
3+
url = https://github.com/abseil/abseil-cpp.git
4+
[submodule "tokenizer/third-party/re2"]
5+
path = tokenizer/third-party/re2
6+
url = https://github.com/google/re2.git

CMakeLists.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
cmake_minimum_required(VERSION 3.24)
2+
set(CMAKE_CXX_STANDARD 17)
3+
IF(DEFINED ENV{TORCHCHAT_ROOT})
4+
set(TORCHCHAT_ROOT $ENV{TORCHCHAT_ROOT})
5+
ELSE()
6+
set(TORCHCHAT_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/..)
7+
ENDIF()
8+
9+
project(Torchchat)
10+
11+
# include tokenizer
12+
add_subdirectory(tokenizer)
13+
14+
# include et_run executable
15+
include(runner/et.cmake)
16+
if(TARGET et_run)
17+
target_link_libraries(et_run PUBLIC tokenizer)
18+
endif()
19+
20+
# include aoti_run executable
21+
include(runner/aoti.cmake)
22+
if(TARGET aoti_run)
23+
target_link_libraries(aoti_run tokenizer)
24+
endif()

runner-aoti/CMakeLists.txt

Lines changed: 0 additions & 17 deletions
This file was deleted.

runner-aoti/run.cpp

Lines changed: 0 additions & 6 deletions
This file was deleted.

runner-et/CMakeLists.txt

Lines changed: 0 additions & 89 deletions
This file was deleted.

runner-et/run.cpp

Lines changed: 0 additions & 6 deletions
This file was deleted.
File renamed without changes.

runner/aoti.cmake

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
cmake_minimum_required(VERSION 3.24)
2+
set(CMAKE_CXX_STANDARD 17)
3+
IF(DEFINED ENV{TORCHCHAT_ROOT})
4+
set(TORCHCHAT_ROOT $ENV{TORCHCHAT_ROOT})
5+
ELSE()
6+
set(TORCHCHAT_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/..)
7+
ENDIF()
8+
9+
find_package(CUDA)
10+
11+
find_package(Torch)
12+
if(Torch_FOUND)
13+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g ${TORCH_CXX_FLAGS} -fpermissive")
14+
15+
add_executable(aoti_run runner/run.cpp)
16+
17+
target_compile_options(aoti_run PUBLIC -D__AOTI_MODEL__)
18+
target_include_directories(aoti_run PRIVATE ${TORCHCHAT_ROOT}/runner)
19+
target_link_libraries(aoti_run "${TORCH_LIBRARIES}" m)
20+
set_property(TARGET aoti_run PROPERTY CXX_STANDARD 17)
21+
endif()

runner-et/build_android.sh renamed to runner/build_android.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ export CMAKE_OUT_DIR="cmake-out-android"
3030
#
3131

3232
build_runner_et() {
33-
rm -rf build/cmake-out-android
33+
rm -rf cmake-out-android
3434
echo "ET BUILD DIR IS ${ET_BUILD_DIR}"
35-
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-23 -S ./runner-et -B build/cmake-out-android -G Ninja
36-
cmake --build build/cmake-out-android/ -j16 --config Release
35+
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-23 -S . -B cmake-out-android -G Ninja
36+
cmake --build cmake-out-android/ -j16 --config Release --target et_run
3737
}
3838

3939
find_cmake_prefix_path

runner/et.cmake

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
cmake_minimum_required(VERSION 3.24)
2+
set(CMAKE_CXX_STANDARD 17)
3+
4+
IF(DEFINED ENV{ET_BUILD_DIR})
5+
set(ET_BUILD_DIR $ENV{ET_BUILD_DIR})
6+
ELSE()
7+
set(ET_BUILD_DIR "et-build")
8+
ENDIF()
9+
10+
MESSAGE(STATUS "Using ET BUILD DIR: --[${ET_BUILD_DIR}]--")
11+
12+
IF(DEFINED ENV{CMAKE_OUT_DIR})
13+
set(CMAKE_OUT_DIR $ENV{CMAKE_OUT_DIR})
14+
ELSE()
15+
set(CMAKE_OUT_DIR "cmake-out")
16+
ENDIF()
17+
18+
MESSAGE(STATUS "Using ET BUILD DIR: --[${ET_BUILD_DIR}]--")
19+
20+
IF(DEFINED ENV{TORCHCHAT_ROOT})
21+
set(TORCHCHAT_ROOT $ENV{TORCHCHAT_ROOT})
22+
ELSE()
23+
set(TORCHCHAT_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/..)
24+
ENDIF()
25+
26+
project(Torchchat)
27+
28+
include(CMakePrintHelpers)
29+
include(runner/Utils.cmake)
30+
31+
cmake_print_variables(TORCHCHAT_ROOT)
32+
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})
36+
if(executorch_FOUND)
37+
set(_common_include_directories ${TORCHCHAT_ROOT}/${ET_BUILD_DIR}/src)
38+
39+
cmake_print_variables(_common_include_directories)
40+
41+
target_include_directories(executorch INTERFACE ${_common_include_directories}) # Ideally ExecuTorch installation process would do this
42+
add_executable(et_run runner/run.cpp)
43+
44+
target_compile_options(et_run PUBLIC -D__ET__MODEL -D_GLIBCXX_USE_CXX11_ABI=1)
45+
46+
# Link ET runtime + extensions
47+
target_link_libraries(
48+
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
64+
)
65+
target_link_options_shared_lib(optimized_native_cpu_ops_lib)
66+
target_link_options_shared_lib(quantized_ops_lib)
67+
target_link_options_shared_lib(xnnpack_backend)
68+
# Not clear why linking executorch as whole-archive outside android/apple is leading
69+
# to double registration. Most likely because of linkage issues.
70+
# Will figure this out later. Until then use this.
71+
if(ANDROID OR APPLE)
72+
target_link_options_shared_lib(executorch)
73+
endif()
74+
75+
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+
78+
# This one is needed for cpuinfo where it uses android specific log lib
79+
if(ANDROID)
80+
target_link_libraries(et_run PRIVATE log)
81+
endif()
82+
83+
# Adding target_link_options_shared_lib as commented out below leads to this:
84+
#
85+
# CMake Error at Utils.cmake:22 (target_link_options):
86+
# Cannot specify link options for target
87+
# "/Users/scroy/etorch/torchchat/et-build/src/executorch/${CMAKE_OUT_DIR}/examples/models/llama2/custom_ops/libcustom_ops_lib.a"
88+
# which is not built by this project.
89+
# Call Stack (most recent call first):
90+
# Utils.cmake:30 (macos_kernel_link_options)
91+
# CMakeLists.txt:41 (target_link_options_shared_lib)
92+
#
93+
#target_link_options_shared_lib("${TORCHCHAT_ROOT}/et-build/src/executorch/${CMAKE_OUT_DIR}/examples/models/llama2/custom_ops/libcustom_ops_lib.a") # This one does not get installed by ExecuTorch
94+
95+
# This works on mac, but appears to run into issues on linux
96+
# It is needed to solve:
97+
# E 00:00:00.055965 executorch:method.cpp:536] Missing operator: [8] llama::sdpa_with_kv_cache.out
98+
endif()

runner/run.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
/* Inference for Llama-2 Transformer model in pure C++ */
2-
32
#include <ctype.h>
43
#include <math.h>
54
#include <stdint.h>
@@ -397,7 +396,7 @@ void generate(
397396
}
398397

399398
// encode the (string) prompt into tokens sequence
400-
std::string prompt_str(prompt);
399+
std::string prompt_str = prompt;
401400
std::vector<uint64_t> prompt_tokens = tokenizer->encode(prompt_str, 1, 0);
402401
int num_prompt_tokens = prompt_tokens.size();
403402
if (num_prompt_tokens < 1) {
@@ -674,9 +673,23 @@ int main(int argc, char* argv[]) {
674673
build_transformer(&transformer, checkpoint_path, vocab_size, steps);
675674

676675
// build the Tokenizer via the tokenizer .bin file
677-
Tokenizer* tokenizer =
678-
new BPETokenizer(transformer.config.vocab_size, /*bos*/ 1, /*eos*/ 2);
679-
tokenizer->load(tokenizer_path);
676+
Tokenizer* tokenizer = nullptr;
677+
678+
// Try to load using Tiktoken, if exception then switch to another tokenizer
679+
try {
680+
tokenizer =
681+
new Tiktoken(transformer.config.vocab_size, /*bos*/ 1, /*eos*/ 2);
682+
tokenizer->load(tokenizer_path);
683+
} catch (const std::invalid_argument&) {
684+
fprintf(
685+
stderr,
686+
"Failed to load %s into a Tiktoken tokenizer. Trying sentencepiece tokenizer..\n",
687+
tokenizer_path);
688+
delete tokenizer;
689+
tokenizer =
690+
new BPETokenizer(transformer.config.vocab_size, /*bos*/ 1, /*eos*/ 2);
691+
tokenizer->load(tokenizer_path);
692+
}
680693

681694
// build the Sampler
682695
Sampler sampler;

0 commit comments

Comments
 (0)