blingBillie commited on
Commit
d443007
1 Parent(s): 5ff56f1

Upload 138 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +2 -0
  2. mlc-llm-main/.clang-format +8 -0
  3. mlc-llm-main/.gitignore +323 -0
  4. mlc-llm-main/.gitmodules +6 -0
  5. mlc-llm-main/3rdparty/tokenizers-cpp/CMakeLists.txt +81 -0
  6. mlc-llm-main/3rdparty/tokenizers-cpp/Cargo.toml +13 -0
  7. mlc-llm-main/3rdparty/tokenizers-cpp/src/lib.rs +187 -0
  8. mlc-llm-main/3rdparty/tokenizers-cpp/tokenizers.h +101 -0
  9. mlc-llm-main/CMakeLists.txt +148 -0
  10. mlc-llm-main/LICENSE +201 -0
  11. mlc-llm-main/README.md +65 -0
  12. mlc-llm-main/android/.gitignore +3 -0
  13. mlc-llm-main/android/MLCChat/.gitignore +15 -0
  14. mlc-llm-main/android/MLCChat/app/.gitignore +1 -0
  15. mlc-llm-main/android/MLCChat/app/build.gradle +71 -0
  16. mlc-llm-main/android/MLCChat/app/proguard-rules.pro +21 -0
  17. mlc-llm-main/android/MLCChat/app/src/main/AndroidManifest.xml +36 -0
  18. mlc-llm-main/android/MLCChat/app/src/main/ic_launcher-playstore.png +0 -0
  19. mlc-llm-main/android/MLCChat/app/src/main/java/ai/mlc/mlcchat/ChatState.java +117 -0
  20. mlc-llm-main/android/MLCChat/app/src/main/java/ai/mlc/mlcchat/Config.java +12 -0
  21. mlc-llm-main/android/MLCChat/app/src/main/java/ai/mlc/mlcchat/Downloader.java +109 -0
  22. mlc-llm-main/android/MLCChat/app/src/main/java/ai/mlc/mlcchat/LLMChat.java +97 -0
  23. mlc-llm-main/android/MLCChat/app/src/main/java/ai/mlc/mlcchat/MainActivity.java +178 -0
  24. mlc-llm-main/android/MLCChat/app/src/main/java/ai/mlc/mlcchat/MessageAdapter.java +83 -0
  25. mlc-llm-main/android/MLCChat/app/src/main/java/ai/mlc/mlcchat/MessageData.java +26 -0
  26. mlc-llm-main/android/MLCChat/app/src/main/java/ai/mlc/mlcchat/Utils.java +73 -0
  27. mlc-llm-main/android/MLCChat/app/src/main/jni/Android.mk +75 -0
  28. mlc-llm-main/android/MLCChat/app/src/main/jni/Application.mk +5 -0
  29. mlc-llm-main/android/MLCChat/app/src/main/jni/tvm_runtime.h +7 -0
  30. mlc-llm-main/android/MLCChat/app/src/main/res/drawable/bot_rounded_corner.xml +16 -0
  31. mlc-llm-main/android/MLCChat/app/src/main/res/drawable/user_rounded_corner.xml +16 -0
  32. mlc-llm-main/android/MLCChat/app/src/main/res/layout/activity_main.xml +92 -0
  33. mlc-llm-main/android/MLCChat/app/src/main/res/layout/bot_message.xml +30 -0
  34. mlc-llm-main/android/MLCChat/app/src/main/res/layout/user_message.xml +30 -0
  35. mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +5 -0
  36. mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +5 -0
  37. mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  38. mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png +0 -0
  39. mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
  40. mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  41. mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png +0 -0
  42. mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
  43. mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  44. mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png +0 -0
  45. mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
  46. mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  47. mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png +0 -0
  48. mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
  49. mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  50. mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png +0 -0
.gitattributes CHANGED
@@ -32,3 +32,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
32
  *.zip filter=lfs diff=lfs merge=lfs -text
33
  *.zst filter=lfs diff=lfs merge=lfs -text
34
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
32
  *.zip filter=lfs diff=lfs merge=lfs -text
33
  *.zst filter=lfs diff=lfs merge=lfs -text
34
  *tfevents* filter=lfs diff=lfs merge=lfs -text
35
+ mlc-llm-main/site/gif/ios-demo.gif filter=lfs diff=lfs merge=lfs -text
36
+ mlc-llm-main/site/img/android/android-studio.png filter=lfs diff=lfs merge=lfs -text
mlc-llm-main/.clang-format ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ # Run the following command to reformat a file:
2
+ # clang-format -i -style=Google <file>
3
+ # Or use clang-format-diff to only reformat the changed lines:
4
+ # https://clang.llvm.org/docs/ClangFormat.html
5
+ BasedOnStyle: Google
6
+ DerivePointerAlignment: false
7
+ ColumnLimit: 100
8
+ PointerAlignment: Left
mlc-llm-main/.gitignore ADDED
@@ -0,0 +1,323 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ dist/
2
+ params/
3
+ *.bak
4
+ # Byte-compiled / optimized / DLL files
5
+ __pycache__/
6
+ *.py[cod]
7
+ *$py.class
8
+
9
+ .DS_Store
10
+
11
+ *.S
12
+ # C extensions
13
+ *.so
14
+
15
+ build*
16
+
17
+ *.ll
18
+ .npm
19
+ # Distribution / packaging
20
+ .Python
21
+ env/
22
+ build/
23
+ build-*/
24
+ develop-eggs/
25
+ dist/
26
+ downloads/
27
+ eggs/
28
+ .eggs/
29
+ lib/
30
+ lib64/
31
+ parts/
32
+ sdist/
33
+ var/
34
+ wheels/
35
+ pip-wheel-metadata/
36
+ share/python-wheels/
37
+ *.egg-info/
38
+ .installed.cfg
39
+ *.egg
40
+ MANIFEST
41
+
42
+ .conda/
43
+ # PyInstaller
44
+ # Usually these files are written by a python script from a template
45
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
46
+ *.manifest
47
+ *.spec
48
+
49
+ # Generated by python/gen_requirements.py
50
+ python/requirements/*.txt
51
+
52
+ # Installer logs
53
+ pip-log.txt
54
+ pip-delete-this-directory.txt
55
+
56
+ # Unit test / coverage reports
57
+ htmlcov/
58
+ .tox/
59
+ .nox/
60
+ .coverage
61
+ .coverage.*
62
+ .cache
63
+ nosetests.xml
64
+ coverage.xml
65
+ *.cover
66
+ *.py,cover
67
+ .hypothesis/
68
+ .pytest_cache/
69
+
70
+ # Translations
71
+ *.mo
72
+ *.pot
73
+
74
+ # Django stuff:
75
+ *.log
76
+ local_settings.py
77
+ db.sqlite3
78
+ db.sqlite3-journal
79
+
80
+ # Flask stuff:
81
+ instance/
82
+ .webassets-cache
83
+
84
+ # Scrapy stuff:
85
+ .scrapy
86
+
87
+ # Sphinx documentation
88
+ docs/_build/
89
+ docs/_staging/
90
+
91
+ # PyBuilder
92
+ target/
93
+ /target/
94
+
95
+ # Jupyter Notebook
96
+ .ipynb_checkpoints
97
+
98
+ # IPython
99
+ profile_default/
100
+ ipython_config.py
101
+
102
+ # pyenv
103
+ .python-version
104
+
105
+ # pipenv
106
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
107
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
108
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
109
+ # install all needed dependencies.
110
+ #Pipfile.lock
111
+
112
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
113
+ __pypackages__/
114
+
115
+ # Celery stuff
116
+ celerybeat-schedule
117
+ celerybeat.pid
118
+
119
+ # SageMath parsed files
120
+ *.sage.py
121
+
122
+ # Environments
123
+ .env
124
+ .venv
125
+ env/
126
+ venv/
127
+ ENV/
128
+ env.bak/
129
+ venv.bak/
130
+
131
+ # Spyder project settings
132
+ .spyderproject
133
+ .spyproject
134
+
135
+ # Rope project settings
136
+ .ropeproject
137
+ *~
138
+ *.pyc
139
+ *~
140
+ config.mk
141
+ config.cmake
142
+ Win32
143
+ *.dir
144
+ perf
145
+ *.wasm
146
+ .emscripten
147
+
148
+ ## IOS
149
+ DerivedData/
150
+
151
+ ## Java
152
+ *.class
153
+ jvm/*/target/
154
+ jvm/*/*/target/
155
+ jvm/native/*/generated
156
+ jvm/native/src/main/native/org_apache_tvm_native_c_api.h
157
+ *.worksheet
158
+ *.idea
159
+ *.iml
160
+ *.classpath
161
+ *.project
162
+ *.settings
163
+ */node_modules/
164
+
165
+ ## Various settings
166
+ *.pbxuser
167
+ !default.pbxuser
168
+ *.mode1v3
169
+ !default.mode1v3
170
+ *.mode2v3
171
+ !default.mode2v3
172
+ *.perspectivev3
173
+ !default.perspectivev3
174
+ xcuserdata/
175
+ .pkl_memoize_*
176
+
177
+ .emscripten*
178
+ .m2
179
+
180
+ # Compiled Dynamic libraries
181
+ *.so
182
+ *.dylib
183
+ *.dll
184
+
185
+ # Compiled Object files
186
+ *.slo
187
+ *.lo
188
+ *.o
189
+ *.obj
190
+
191
+ # Precompiled Headers
192
+ *.gch
193
+ *.pch
194
+
195
+ # Compiled Static libraries
196
+ *.lai
197
+ *.la
198
+ *.a
199
+ *.lib
200
+
201
+ # Executables
202
+ *.exe
203
+ *.out
204
+ *.app
205
+
206
+ ## Other
207
+ *.moved-aside
208
+ *.xccheckout
209
+ *.xcscmblueprint
210
+ .DS_Store
211
+ tags
212
+ cscope*
213
+ *.lock
214
+
215
+ # vim temporary files
216
+ *.swp
217
+ *.swo
218
+
219
+ # TVM generated code
220
+ perf
221
+ .bash_history
222
+ # *.json
223
+ *.params
224
+ *.ro
225
+ *.onnx
226
+ *.h5
227
+ synset.txt
228
+ cat.jpg
229
+ cat.png
230
+ docs.tgz
231
+ cat.png
232
+ *.mlmodel
233
+ tvm_u.*
234
+ tvm_t.*
235
+ # Mac OS X
236
+ .DS_Store
237
+
238
+ # Jetbrain
239
+ .idea
240
+ .ipython
241
+ .jupyter
242
+ .nv
243
+ .pylint.d
244
+ .python_history
245
+ .pytest_cache
246
+ .local
247
+ cmake-build-debug
248
+
249
+ # Visual Studio
250
+ .vs
251
+
252
+ # Visual Studio Code
253
+ .vscode
254
+
255
+ # tmp file
256
+ .nfs*
257
+
258
+ # keys
259
+ *.pem
260
+ *.p12
261
+ *.pfx
262
+ *.cer
263
+ *.crt
264
+ *.der
265
+
266
+ # patch sentinel
267
+ patched.txt
268
+
269
+ # Python type checking
270
+ .mypy_cache/
271
+ .pyre/
272
+
273
+ # pipenv files
274
+ Pipfile
275
+ Pipfile.lock
276
+
277
+ # conda package artifacts
278
+ conda/Dockerfile.cuda*
279
+ conda/pkg
280
+ .node_repl_history
281
+ # nix files
282
+ .envrc
283
+ *.nix
284
+
285
+ # Docker files
286
+ .sudo_as_admin_successful
287
+
288
+ # Downloaded models/datasets
289
+ .tvm_test_data
290
+ .dgl
291
+ .caffe2
292
+
293
+ # Local docs build
294
+ _docs/
295
+ jvm/target
296
+ .config/configstore/
297
+ .ci-py-scripts/
298
+
299
+ # Generated Hexagon files
300
+ src/runtime/hexagon/rpc/hexagon_rpc.h
301
+ src/runtime/hexagon/rpc/hexagon_rpc_skel.c
302
+ src/runtime/hexagon/rpc/hexagon_rpc_stub.c
303
+
304
+ # Local tvm-site checkout
305
+ tvm-site/
306
+
307
+ # Generated docs files
308
+ gallery/how_to/work_with_microtvm/micro_tvmc.py
309
+
310
+ # Test sample data files
311
+ !tests/python/ci/sample_prs/*.json
312
+
313
+ # Used in CI to communicate between Python and Jenkins
314
+ .docker-image-names/
315
+
316
+ # Printed TIR code on disk
317
+ *.tir
318
+
319
+ # GDB history file
320
+ .gdb_history
321
+
322
+ 3rdparty
323
+ dist
mlc-llm-main/.gitmodules ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ [submodule "3rdparty/sentencepiece-js"]
2
+ path = 3rdparty/sentencepiece-js
3
+ url = https://github.com/tqchen/sentencepiece-js
4
+ [submodule "3rdparty/argparse"]
5
+ path = 3rdparty/argparse
6
+ url = https://github.com/p-ranav/argparse
mlc-llm-main/3rdparty/tokenizers-cpp/CMakeLists.txt ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # update to contain more rust flags
2
+ set(TOKENIZERS_CPP_RUST_FLAGS "")
3
+ set(TOKENIZERS_CPP_CARGO_TARGET "")
4
+
5
+ # extra link libraries
6
+ set(TOKENIZERS_CPP_LINK_LIBS "")
7
+ set(CARGO_EXTRA_ENVS "")
8
+
9
+ if (CMAKE_SYSTEM_NAME STREQUAL "iOS")
10
+ set(TOKENIZERS_CPP_CARGO_TARGET aarch64-apple-ios)
11
+ # add extra dependency needed for rust tokenizer in iOS
12
+ find_library(FOUNDATION_LIB Foundation)
13
+ find_library(SECURITY_LIB Security)
14
+ list(APPEND TOKENIZERS_CPP_LINK_LIBS ${FOUNDATION_LIB} ${SECURITY_LIB})
15
+ elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
16
+ if (CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
17
+ set(TOKENIZERS_CPP_CARGO_TARGET aarch64-apple-darwin)
18
+ endif()
19
+ elseif (CMAKE_SYSTEM_NAME STREQUAL "Android")
20
+ set(TOKENIZERS_CPP_CARGO_TARGET aarch64-linux-android)
21
+ set(CARGO_EXTRA_ENVS
22
+ AR_aarch64_linux_android=${ANDROID_TOOLCHAIN_ROOT}/bin/llvm-ar
23
+ CC_aarch64_linux_android=${ANDROID_TOOLCHAIN_ROOT}/bin/aarch64-linux-android${ANDROID_NATIVE_API_LEVEL}-clang
24
+ CXX_aarch64_linux_android=${ANDROID_TOOLCHAIN_ROOT}/bin/aarch64-linux-android${ANDROID_NATIVE_API_LEVEL}-clang++
25
+ )
26
+ elseif (CMAKE_SYSTEM_NAME STREQUAL "Windows")
27
+ set(TOKENIZERS_CPP_CARGO_TARGET x86_64-pc-windows-msvc)
28
+ endif()
29
+
30
+ if(WIN32)
31
+ list(APPEND TOKENIZERS_CPP_LINK_LIBS
32
+ wsock32 ws2_32 Bcrypt
33
+ iphlpapi userenv psapi
34
+ )
35
+ endif()
36
+
37
+ set(TOKENIZERS_CPP_CARGO_FLAGS "")
38
+ set(TOKENIZERS_CPP_CARGO_TARGET_DIR ${CMAKE_CURRENT_BINARY_DIR})
39
+ set(TOKENIZERS_CPP_CARGO_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
40
+
41
+ if (NOT TOKENIZERS_CPP_CARGO_TARGET STREQUAL "")
42
+ list(APPEND TOKENIZERS_CPP_CARGO_FLAGS --target ${TOKENIZERS_CPP_CARGO_TARGET})
43
+ set(TOKENIZERS_CPP_CARGO_BINARY_DIR
44
+ "${TOKENIZERS_CPP_CARGO_BINARY_DIR}/${TOKENIZERS_CPP_CARGO_TARGET}")
45
+ endif()
46
+
47
+ if (CMAKE_BUILD_TYPE STREQUAL "Debug")
48
+ set(TOKENIZERS_CPP_CARGO_BINARY_DIR "${TOKENIZERS_CPP_CARGO_BINARY_DIR}/debug")
49
+ else ()
50
+ list(APPEND TOKENIZERS_CPP_CARGO_FLAGS --release)
51
+ set(TOKENIZERS_CPP_CARGO_BINARY_DIR "${TOKENIZERS_CPP_CARGO_BINARY_DIR}/release")
52
+ endif ()
53
+
54
+ get_filename_component(TOKENIZERS_CPP_CARGO_SOURCE_PATH ${CMAKE_CURRENT_LIST_FILE} DIRECTORY)
55
+
56
+ if(MSVC)
57
+ set(TOKENIZERS_CPP_LIB "${TOKENIZERS_CPP_CARGO_BINARY_DIR}/tokenizers_cpp.lib")
58
+ else()
59
+ set(TOKENIZERS_CPP_LIB "${TOKENIZERS_CPP_CARGO_BINARY_DIR}/libtokenizers_cpp.a")
60
+ endif()
61
+ set(TOKENIZERS_CPP_INCLUDE ${TOKENIZERS_CPP_CARGO_SOURCE_PATH})
62
+
63
+ # NOTE: need to use cmake -E env to be portable in win
64
+
65
+ add_custom_command(
66
+ OUTPUT ${TOKENIZERS_CPP_LIB}
67
+ COMMAND
68
+ ${CMAKE_COMMAND} -E env
69
+ CARGO_TARGET_DIR=${TOKENIZERS_CPP_CARGO_TARGET_DIR}
70
+ ${CARGO_EXTRA_ENVS}
71
+ RUSTFLAGS="${TOKENIZERS_CPP_RUST_FLAGS}"
72
+ cargo build ${TOKENIZERS_CPP_CARGO_FLAGS}
73
+ WORKING_DIRECTORY ${TOKENIZERS_CPP_CARGO_SOURCE_PATH}
74
+ POST_BUILD COMMAND
75
+ ${CMAKE_COMMAND} -E copy
76
+ ${TOKENIZERS_CPP_LIB} "${CMAKE_CURRENT_BINARY_DIR}"
77
+ )
78
+
79
+ add_library(tokenizers INTERFACE ${TOKENIZERS_CPP_LIB})
80
+ target_link_libraries(tokenizers INTERFACE ${TOKENIZERS_CPP_LIB} ${TOKENIZERS_CPP_LINK_LIBS})
81
+ target_include_directories(tokenizers INTERFACE ${TOKENIZERS_CPP_INCLUDE})
mlc-llm-main/3rdparty/tokenizers-cpp/Cargo.toml ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [package]
2
+ name = "tokenizers-cpp"
3
+ version = "0.1.0"
4
+ edition = "2018"
5
+
6
+ [lib]
7
+ crate-type = ["staticlib"]
8
+
9
+ [dependencies]
10
+
11
+ tokenizers = { version = "0.13.3", default-features = false, features = ["onig"] }
12
+ serde = { version = "1.0", features = [ "derive" ] }
13
+ serde_json = "1.0"
mlc-llm-main/3rdparty/tokenizers-cpp/src/lib.rs ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // A simple C wrapper of tokenzier library
2
+ use serde_json::Value;
3
+ use std::{collections::HashMap, str::FromStr};
4
+ use tokenizers::models::bpe::BPE;
5
+ use tokenizers::pre_tokenizers::byte_level::ByteLevel;
6
+ use tokenizers::tokenizer::Tokenizer;
7
+
8
+ pub struct TokenizerWrapper {
9
+ tokenizer: Tokenizer,
10
+ encode_ids: Vec<u32>,
11
+ decode_str: String,
12
+ }
13
+
14
+ pub type Vocab = HashMap<String, u32>;
15
+ pub type Merges = Vec<(String, String)>;
16
+
17
+ impl TokenizerWrapper {
18
+ pub fn from_str(json: &str) -> TokenizerWrapper {
19
+ TokenizerWrapper {
20
+ tokenizer: Tokenizer::from_str(json).unwrap().into(),
21
+ encode_ids: Vec::new(),
22
+ decode_str: String::new(),
23
+ }
24
+ }
25
+
26
+ pub fn byte_level_bpe_from_str(
27
+ vocab: &str,
28
+ merges: &str,
29
+ added_tokens: &str,
30
+ ) -> TokenizerWrapper {
31
+ let vocab_json: Value = serde_json::from_str(vocab).unwrap();
32
+ let added_tokens_json: Value = serde_json::from_str(added_tokens).unwrap();
33
+ let mut vocab = HashMap::new();
34
+ match vocab_json {
35
+ Value::Object(m) => {
36
+ for (token, id) in m {
37
+ if let Value::Number(id) = id {
38
+ let id = id.as_u64().unwrap() as u32;
39
+ vocab.insert(token, id);
40
+ }
41
+ }
42
+ }
43
+ _ => panic!("Invalid vocab.json file."),
44
+ };
45
+ match added_tokens_json {
46
+ Value::Object(m) => {
47
+ for (token, id) in m {
48
+ if let Value::Number(id) = id {
49
+ let id = id.as_u64().unwrap() as u32;
50
+ vocab.insert(token, id);
51
+ }
52
+ }
53
+ }
54
+ _ => panic!("Invalid added_tokens.json file."),
55
+ }
56
+
57
+ let merges = merges
58
+ .lines()
59
+ .filter(|line| !line.starts_with("#version"))
60
+ .map(|line| {
61
+ let parts = line.split(' ').collect::<Vec<_>>();
62
+ if parts.len() != 2 {
63
+ panic!("Invalid merges.txt file.")
64
+ }
65
+ return (parts[0].to_string(), parts[1].to_string()); // Add the `return` keyword here
66
+ })
67
+ .collect::<Vec<(String, String)>>();
68
+ let byte_level = ByteLevel::new(
69
+ /*add_prefix_space=*/ false, /*trim_offsets=*/ false,
70
+ /*use_regex=*/ false,
71
+ );
72
+ let mut tokenizer = Tokenizer::new(BPE::new(vocab, merges));
73
+ tokenizer
74
+ .with_pre_tokenizer(byte_level)
75
+ .with_decoder(byte_level);
76
+ TokenizerWrapper {
77
+ tokenizer: tokenizer,
78
+ encode_ids: Vec::new(),
79
+ decode_str: String::new(),
80
+ }
81
+ }
82
+
83
+ pub fn encode(&mut self, text: &str, add_special_tokens: bool) {
84
+ self.encode_ids = Vec::from(
85
+ self.tokenizer
86
+ .encode(text, add_special_tokens)
87
+ .unwrap()
88
+ .get_ids(),
89
+ );
90
+ }
91
+
92
+ pub fn decode(&mut self, ids: Vec<u32>, skip_special_tokens: bool) {
93
+ self.decode_str = self.tokenizer.decode(ids, skip_special_tokens).unwrap();
94
+ }
95
+ }
96
+
97
+ #[no_mangle]
98
+ extern "C" fn tokenizers_new_from_str(input_cstr: *const u8, len: usize) -> *mut TokenizerWrapper {
99
+ unsafe {
100
+ let json = std::str::from_utf8(std::slice::from_raw_parts(input_cstr, len)).unwrap();
101
+ return Box::into_raw(Box::new(TokenizerWrapper::from_str(json)));
102
+ }
103
+ }
104
+
105
+ #[no_mangle]
106
+ extern "C" fn byte_level_bpe_tokenizers_new_from_str(
107
+ input_vocab_str: *const u8,
108
+ len_vocab: usize,
109
+ input_merges_str: *const u8,
110
+ len_merges: usize,
111
+ input_added_tokens_str: *const u8,
112
+ len_added_tokens: usize,
113
+ ) -> *mut TokenizerWrapper {
114
+ unsafe {
115
+ let vocab =
116
+ std::str::from_utf8(std::slice::from_raw_parts(input_vocab_str, len_vocab)).unwrap();
117
+ let merges =
118
+ std::str::from_utf8(std::slice::from_raw_parts(input_merges_str, len_merges)).unwrap();
119
+ let added_tokens = std::str::from_utf8(std::slice::from_raw_parts(
120
+ input_added_tokens_str,
121
+ len_added_tokens,
122
+ ))
123
+ .unwrap();
124
+ return Box::into_raw(Box::new(TokenizerWrapper::byte_level_bpe_from_str(
125
+ vocab,
126
+ merges,
127
+ added_tokens,
128
+ )));
129
+ }
130
+ }
131
+
132
+ #[no_mangle]
133
+ extern "C" fn tokenizers_encode(
134
+ handle: *mut TokenizerWrapper,
135
+ input_cstr: *const u8,
136
+ len: usize,
137
+ add_special_tokens: i32,
138
+ ) {
139
+ unsafe {
140
+ let input_data = std::str::from_utf8(std::slice::from_raw_parts(input_cstr, len)).unwrap();
141
+ (*handle).encode(input_data, add_special_tokens != 0);
142
+ }
143
+ }
144
+
145
+ #[no_mangle]
146
+ extern "C" fn tokenizers_get_encode_ids(
147
+ handle: *mut TokenizerWrapper,
148
+ out_data: *mut *mut u32,
149
+ out_len: *mut usize,
150
+ ) {
151
+ unsafe {
152
+ *out_data = (*handle).encode_ids.as_mut_ptr();
153
+ *out_len = (*handle).encode_ids.len()
154
+ }
155
+ }
156
+
157
+ #[no_mangle]
158
+ extern "C" fn tokenizers_decode(
159
+ handle: *mut TokenizerWrapper,
160
+ input_ids: *const u32,
161
+ len: usize,
162
+ skip_special_tokens: i32,
163
+ ) {
164
+ unsafe {
165
+ let input_data = Vec::from(std::slice::from_raw_parts(input_ids, len));
166
+ (*handle).decode(input_data, skip_special_tokens != 0);
167
+ }
168
+ }
169
+
170
+ #[no_mangle]
171
+ extern "C" fn tokenizers_get_decode_str(
172
+ handle: *mut TokenizerWrapper,
173
+ out_cstr: *mut *mut u8,
174
+ out_len: *mut usize,
175
+ ) {
176
+ unsafe {
177
+ *out_cstr = (*handle).decode_str.as_mut_ptr();
178
+ *out_len = (*handle).decode_str.len();
179
+ }
180
+ }
181
+
182
+ #[no_mangle]
183
+ extern "C" fn tokenizers_free(wrapper: *mut TokenizerWrapper) {
184
+ unsafe {
185
+ drop(Box::from_raw(wrapper));
186
+ }
187
+ }
mlc-llm-main/3rdparty/tokenizers-cpp/tokenizers.h ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * Copyright (c) 2023 by Contributors
3
+ * \file tokenizers.cc
4
+ * \brief C binding to tokenizers
5
+ */
6
+ #ifndef TOKENIZERS_H_
7
+ #define TOKENIZERS_H_
8
+
9
+ // The C API
10
+ #ifdef __cplusplus
11
+ extern "C" {
12
+ #endif
13
+
14
+ #include <stddef.h>
15
+ #include <stdint.h>
16
+
17
+ typedef void* TokenizerHandle;
18
+
19
+ TokenizerHandle tokenizers_new_from_str(const char* json, size_t len);
20
+
21
+ TokenizerHandle byte_level_bpe_tokenizers_new_from_str(const char* vocab, size_t vocab_len,
22
+ const char* merges, size_t merges_len,
23
+ const char* added_tokens,
24
+ size_t added_tokens_len);
25
+
26
+ void tokenizers_encode(TokenizerHandle handle, const char* data, size_t len, int add_special_token);
27
+
28
+ void tokenizers_decode(TokenizerHandle handle, const uint32_t* data, size_t len,
29
+ int skip_special_token);
30
+
31
+ void tokenizers_get_decode_str(TokenizerHandle handle, const char** data, size_t* len);
32
+
33
+ void tokenizers_get_encode_ids(TokenizerHandle handle, const uint32_t** id_data, size_t* len);
34
+
35
+ void tokenizers_free(TokenizerHandle handle);
36
+
37
+ #ifdef __cplusplus
38
+ }
39
+ #endif
40
+
41
+ #ifdef __cplusplus
42
+
43
+ #include <string>
44
+ #include <vector>
45
+
46
+ // simple c++ binding
47
+ namespace tokenizers {
48
+
49
+ /*!
50
+ * \brief A simple c++ header of tokenizer via C API.
51
+ */
52
+ class Tokenizer {
53
+ public:
54
+ Tokenizer(const Tokenizer&) = delete;
55
+ Tokenizer(Tokenizer&& other) { std::swap(other.handle_, handle_); }
56
+
57
+ ~Tokenizer() {
58
+ if (handle_ != nullptr) {
59
+ tokenizers_free(handle_);
60
+ }
61
+ }
62
+
63
+ // use i32 to be consistent with sentencepiece
64
+ std::vector<int32_t> Encode(const std::string& text, bool add_special_token) {
65
+ tokenizers_encode(handle_, text.data(), text.length(), static_cast<int>(add_special_token));
66
+ const uint32_t* data;
67
+ size_t len;
68
+ tokenizers_get_encode_ids(handle_, &data, &len);
69
+ return std::vector<int32_t>(data, data + len);
70
+ }
71
+
72
+ // use i32 to be consistent with sentencepiece
73
+ std::string Decode(const std::vector<int32_t>& ids, bool skip_special_token) {
74
+ tokenizers_decode(handle_, reinterpret_cast<const uint32_t*>(ids.data()), ids.size(),
75
+ static_cast<int>(skip_special_token));
76
+ const char* data;
77
+ size_t len;
78
+ tokenizers_get_decode_str(handle_, &data, &len);
79
+ return std::string(data, len);
80
+ }
81
+
82
+ // avoid from_file so we don't have file system
83
+ static Tokenizer FromJSON(const std::string& json) {
84
+ return Tokenizer(tokenizers_new_from_str(json.data(), json.length()));
85
+ }
86
+
87
+ static Tokenizer FromBPE(const std::string& vocab, const std::string& merges,
88
+ const std::string& added_tokens) {
89
+ return Tokenizer(byte_level_bpe_tokenizers_new_from_str(
90
+ vocab.data(), vocab.length(), merges.data(), merges.length(), added_tokens.data(),
91
+ added_tokens.length()));
92
+ }
93
+
94
+ private:
95
+ Tokenizer(TokenizerHandle handle) : handle_(handle) {}
96
+ // internal handle
97
+ TokenizerHandle handle_{nullptr};
98
+ };
99
+ } // namespace tokenizers
100
+ #endif
101
+ #endif // TOKENIZERS_H_
mlc-llm-main/CMakeLists.txt ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ cmake_minimum_required(VERSION 3.18)
2
+ project(mlc_llm C CXX)
3
+
4
+ include(CheckCXXCompilerFlag)
5
+ if(NOT MSVC)
6
+ check_cxx_compiler_flag("-std=c++17" SUPPORT_CXX17)
7
+ set(CMAKE_CXX_FLAGS "-std=c++17 ${CMAKE_CXX_FLAGS}")
8
+ set(CMAKE_CUDA_STANDARD 17)
9
+ else()
10
+ check_cxx_compiler_flag("/std:c++17" SUPPORT_CXX17)
11
+ set(CMAKE_CXX_FLAGS "/std:c++17 ${CMAKE_CXX_FLAGS}")
12
+ set(CMAKE_CUDA_STANDARD 17)
13
+ endif()
14
+
15
+ if(EXISTS ${CMAKE_BINARY_DIR}/config.cmake)
16
+ include(${CMAKE_BINARY_DIR}/config.cmake)
17
+ else()
18
+ if(EXISTS ${CMAKE_SOURCE_DIR}/config.cmake)
19
+ include(${CMAKE_SOURCE_DIR}/config.cmake)
20
+ endif()
21
+ endif()
22
+
23
+ if(NOT CMAKE_BUILD_TYPE)
24
+ set(
25
+ CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Build type" FORCE
26
+ )
27
+ message(STATUS "Setting default build type to " ${CMAKE_BUILD_TYPE})
28
+ endif(NOT CMAKE_BUILD_TYPE)
29
+
30
+ option(MLC_LLM_INSTALL_STATIC_LIB "Install static lib instead of cli" OFF)
31
+
32
+ if (MLC_LLM_INSTALL_STATIC_LIB)
33
+ set(BUILD_STATIC_RUNTIME ON)
34
+ endif()
35
+
36
+ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
37
+
38
+ # tvm runtime config: minimize runtime components
39
+ set(USE_RPC OFF)
40
+ set(USE_MICRO OFF)
41
+ set(USE_GRAPH_EXECUTOR OFF)
42
+ set(USE_GRAPH_EXECUTOR_DEBUG OFF)
43
+ set(USE_AOT_EXECUTOR OFF)
44
+ set(USE_PROFILER OFF)
45
+ set(USE_GTEST OFF)
46
+ set(USE_LIBBACKTRACE OFF)
47
+ add_subdirectory($ENV{TVM_HOME} tvm EXCLUDE_FROM_ALL)
48
+
49
+ # sentencepiece config
50
+ option(SPM_ENABLE_SHARED "override sentence piece config" OFF)
51
+ option(SPM_ENABLE_TCMALLOC "" OFF)
52
+
53
+
54
+ set(MLC_LLM_RUNTIME_LINKER_LIB "")
55
+ # provide macro if it does not exist in cmake system
56
+ # it is OK to skip those since we do not provide these apps in the ios
57
+ # instead just link to the sentencepiece directly
58
+ if (CMAKE_SYSTEM_NAME STREQUAL "iOS")
59
+ macro (set_xcode_property TARGET XCODE_PROPERTY XCODE_VALUE)
60
+ set_property (TARGET ${TARGET} PROPERTY
61
+ XCODE_ATTRIBUTE_${XCODE_PROPERTY} ${XCODE_VALUE})
62
+ endmacro (set_xcode_property)
63
+ endif()
64
+
65
+ add_subdirectory(3rdparty/sentencepiece-js/sentencepiece sentencepiece EXCLUDE_FROM_ALL)
66
+ add_subdirectory(3rdparty/tokenizers-cpp tokenizers EXCLUDE_FROM_ALL)
67
+
68
+
69
+ tvm_file_glob(GLOB_RECURSE MLC_LLM_SRCS cpp/*.cc)
70
+ tvm_file_glob(GLOB_RECURSE MLC_CLI_SRCS cpp/cli_main.cc)
71
+ list(REMOVE_ITEM MLC_LLM_SRCS ${MLC_CLI_SRCS})
72
+
73
+ add_library(mlc_llm_objs OBJECT ${MLC_LLM_SRCS})
74
+ add_library(mlc_cli_objs OBJECT ${MLC_CLI_SRCS})
75
+
76
+ set(
77
+ MLC_LLM_INCLUDES
78
+ $ENV{TVM_HOME}/include
79
+ $ENV{TVM_HOME}/3rdparty/dlpack/include
80
+ $ENV{TVM_HOME}/3rdparty/dmlc-core/include
81
+ )
82
+
83
+ set(MLC_LLM_COMPILE_DEFS DMLC_USE_LOGGING_LIBRARY=<tvm/runtime/logging.h>)
84
+
85
+ target_include_directories(mlc_llm_objs PRIVATE ${MLC_LLM_INCLUDES})
86
+ target_compile_definitions(mlc_llm_objs PRIVATE ${MLC_LLM_COMPILE_DEFS})
87
+ target_include_directories(mlc_llm_objs PRIVATE 3rdparty/sentencepiece-js/sentencepiece/src)
88
+ target_include_directories(mlc_llm_objs PRIVATE 3rdparty/tokenizers-cpp)
89
+ target_compile_definitions(mlc_llm_objs PRIVATE -DMLC_LLM_EXPORTS)
90
+
91
+ add_library(mlc_llm SHARED $<TARGET_OBJECTS:mlc_llm_objs>)
92
+ add_library(mlc_llm_static STATIC $<TARGET_OBJECTS:mlc_llm_objs>)
93
+ add_dependencies(mlc_llm_static sentencepiece-static tokenizers tvm_runtime)
94
+ set_target_properties(mlc_llm_static PROPERTIES OUTPUT_NAME mlc_llm)
95
+
96
+ target_link_libraries(mlc_llm PUBLIC tvm_runtime)
97
+ target_link_libraries(mlc_llm PRIVATE sentencepiece)
98
+ # note: somehow cmake needs to specify the dependency twice
99
+ target_link_libraries(mlc_llm PRIVATE tokenizers)
100
+
101
+ # Exmaple app that may depends on mlc_llm
102
+ add_executable(mlc_chat_cli $<TARGET_OBJECTS:mlc_cli_objs>)
103
+ target_include_directories(mlc_cli_objs PRIVATE ${MLC_LLM_INCLUDES})
104
+ target_include_directories(mlc_cli_objs PRIVATE 3rdparty/argparse/include)
105
+ target_compile_definitions(mlc_cli_objs PRIVATE ${MLC_LLM_COMPILE_DEFS})
106
+
107
+ if (CMAKE_SYSTEM_NAME STREQUAL "Android")
108
+ target_link_libraries(mlc_llm PRIVATE log)
109
+ target_link_libraries(mlc_chat_cli PRIVATE log)
110
+ endif()
111
+
112
+ if (MLC_LLM_INSTALL_STATIC_LIB)
113
+ target_link_libraries(
114
+ mlc_chat_cli PRIVATE mlc_llm_static sentencepiece-static tokenizers)
115
+ target_link_libraries(
116
+ mlc_chat_cli PRIVATE "$<LINK_LIBRARY:WHOLE_ARCHIVE,tvm_runtime>")
117
+ else()
118
+ target_link_libraries(mlc_chat_cli PUBLIC mlc_llm)
119
+ endif()
120
+
121
+ # when this option is on,
122
+ # we install all static lib deps into lib
123
+ if (MLC_LLM_INSTALL_STATIC_LIB)
124
+ install(TARGETS
125
+ mlc_llm_static
126
+ sentencepiece-static
127
+ tvm_runtime
128
+ LIBRARY DESTINATION lib${LIB_SUFFIX}
129
+ )
130
+ # tokenizers need special handling as it builds from rust
131
+ if(MSVC)
132
+ install(FILES ${CMAKE_BINARY_DIR}/tokenizers/libtokenizers_cpp.lib
133
+ DESTINATION lib${LIB_SUFFIX}
134
+ )
135
+ else()
136
+ install(FILES ${CMAKE_BINARY_DIR}/tokenizers/libtokenizers_cpp.a
137
+ DESTINATION lib${LIB_SUFFIX}
138
+ )
139
+ endif()
140
+ else()
141
+ install(TARGETS mlc_chat_cli tvm_runtime mlc_llm
142
+ mlc_llm_static
143
+ sentencepiece-static
144
+ RUNTIME_DEPENDENCY_SET tokenizers
145
+ RUNTIME DESTINATION bin
146
+ LIBRARY DESTINATION lib${LIB_SUFFIX}
147
+ )
148
+ endif()
mlc-llm-main/LICENSE ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright [yyyy] [name of copyright owner]
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
mlc-llm-main/README.md ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # MLC LLM
2
+
3
+ | [Project](https://mlc.ai/mlc-llm/) | [Blog](https://mlc.ai/blog/blog/2023/05/01/bringing-accelerated-llm-to-consumer-hardware) | [Demo: iOS](https://mlc.ai/mlc-llm/#iphone) | [Demo: Android](https://mlc.ai/mlc-llm/#android) | [Demo: CLI](https://mlc.ai/mlc-llm/#windows-linux-mac) | [WebLLM](https://mlc.ai/web-llm/) | [WebStableDiffusion](https://mlc.ai/web-stable-diffusion/) |
4
+
5
+ MLC LLM is a **universal solution** that allows **any language models** to be **deployed natively** on a diverse set of hardware backends and native applications, plus a **productive framework** for everyone to further optimize model performance for their own use cases.
6
+
7
+ Our mission is to **enable everyone to develop, optimize and deploy AI models natively on everyone's devices**.
8
+
9
+ Everything runs locally with no server support and accelerated with local GPUs on your phone and laptops.
10
+ [Supported platforms](https://github.com/mlc-ai/mlc-llm/issues/15) include:
11
+ * iPhone, iPad;
12
+ * Android phones;
13
+ * Metal GPUs and Intel/ARM MacBooks;
14
+ * AMD, Intel and NVIDIA GPUs via Vulkan on Windows and Linux;
15
+ * NVIDIA GPUs via CUDA on Windows and Linux;
16
+ * WebGPU on browsers (through companion project [WebLLM](https://github.com/mlc-ai/web-llm/tree/main)).
17
+
18
+ **[Check out our instruction page to try out!](https://mlc.ai/mlc-llm/)**
19
+
20
+ <p align="center">
21
+ <img src="site/gif/ios-demo.gif" height="700">
22
+ </p>
23
+
24
+ ## What is MLC LLM?
25
+
26
+ In recent years, there has been remarkable progress in generative artificial intelligence (AI) and large language models (LLMs), which are becoming increasingly prevalent. Thanks to open-source initiatives, it is now possible to develop personal AI assistants using open-sourced models. However, LLMs tend to be resource-intensive and computationally demanding. To create a scalable service, developers may need to rely on powerful clusters and expensive hardware to run model inference. Additionally, deploying LLMs presents several challenges, such as their ever-evolving model innovation, memory constraints, and the need for potential optimization techniques.
27
+
28
+ The goal of this project is to enable the development, optimization, and deployment of AI models for inference across a range of devices, including not just server-class hardware, but also users' browsers, laptops, and mobile apps. To achieve this, we need to address the diverse nature of compute devices and deployment environments. Some of the key challenges include:
29
+
30
+ - Supporting different models of CPUs, GPUs, and potentially other co-processors and accelerators.
31
+ - Deploying on the native environment of user devices, which may not have python or other necessary dependencies readily available.
32
+ - Addressing memory constraints by carefully planning allocation and aggressively compressing model parameters.
33
+
34
+ MLC LLM offers a repeatable, systematic, and customizable workflow that empowers developers and AI system researchers to implement models and optimizations in a productivity-focused, Python-first approach. This methodology enables quick experimentation with new models, new ideas and new compiler passes, followed by native deployment to the desired targets. Furthermore, we are continuously expanding LLM acceleration by broadening TVM backends to make model compilation more transparent and efficient.
35
+
36
+ ## How does MLC Enable Universal Native Deployment?
37
+
38
+ The cornerstone of our solution is machine learning compilation ([MLC](https://mlc.ai/)), which we leverage to efficiently deploy AI models. We build on the shoulders of open-source ecosystems, including tokenizers from HuggingFace and Google, as well as open-source LLMs like Llama, Vicuna, Dolly, MOSS and more. Our primary workflow is based on [Apache TVM Unity](https://github.com/apache/tvm/tree/unity), an exciting ongoing development in the Apache TVM Community.
39
+
40
+ - Dynamic shape: We bake a language model as a TVM IRModule with native dynamic shape support, avoiding the need for extra padding to the maximum length and reducing both computation amount and memory usage.
41
+ - Composable ML compilation optimizations: we perform many model deployment optimizations, such as better compilation code transformation, fusion, memory planning, library offloading and manual code optimization can be easily incorporated as TVM's IRModule transformations exposed as Python APIs.
42
+ - Quantization: We utilize low-bit quantizations to compress the model weights and leverage TVM's loop-level TensorIR to quickly customize code generations for different compression encoding schemes.
43
+ - Runtime: The final generated libraries run on the native environment, with TVM runtime that comes with minimal dependencies, which supports various GPU driver APIs and native language bindings (C, JavaScript, etc).
44
+
45
+ <img src="site/img/diag.svg" alt="Architecture Diagram" height=""/>
46
+
47
+ Additionally, we also provide a lightweight C++-based example CLI app that showcases how to wrap up the compiled artifacts and necessary pre/post-processing, which will hopefully clarify the workflow to embed them into native applications.
48
+
49
+ As a starting point, MLC generates GPU shaders for CUDA, Vulkan and Metal. It is possible to add more support, such as OpenCL, sycl, webgpu-native, through improvements to TVM compiler and runtime. MLC also supports various CPU targets including ARM and x86 via LLVM.
50
+
51
+ We heavily rely on open-source ecosystem, more specifically, [TVM Unity](https://discuss.tvm.apache.org/t/establish-tvm-unity-connection-a-technical-strategy/13344), an exciting latest development in the TVM project that enables python-first interactive MLC development experiences that allows us to easily compose new optimizations all in Python, and incrementally bring our app to the environment of interest. We also leveraged optimizations such as fused quantization kernels, first class dynamic shape support and diverse GPU backends.
52
+
53
+ ## Links
54
+
55
+ - You might also be interested in [WebLLM](https://github.com/mlc-ai/web-llm/tree/main), our companion derived project that focus on bringing LLM to browsers.
56
+ - Project page for [instructions](site/index.md).
57
+ - [Local build Instructions for ios App](ios/README.md).
58
+ - You might want to check out our online public [Machine Learning Compilation course](https://mlc.ai) for a systematic
59
+ walkthrough of our approaches.
60
+
61
+ ## Acknowledgements
62
+
63
+ This project is initiated by members from CMU catalyst, UW SAMPL, SJTU, OctoML and the MLC community. We would love to continue developing and supporting the open-source ML community.
64
+
65
+ This project is only possible thanks to the shoulders open-source ecosystems that we stand on. We want to thank the Apache TVM community and developers of the TVM Unity effort. The open-source ML community members made these models publicly available. PyTorch and Hugging Face communities that make these models accessible. We would like to thank the teams behind Vicuna, SentencePiece, LLaMA, Alpaca and MOSS. We also would like to thank the Vulkan, Swift, C++, Python Rust communities that enables this project.
mlc-llm-main/android/.gitignore ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ MLCChat/app/src/main/jni/*.h
2
+ MLCChat/app/src/main/jni/*.cc
3
+ MLCChat/app/src/main/obj
mlc-llm-main/android/MLCChat/.gitignore ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.iml
2
+ .gradle
3
+ /local.properties
4
+ /.idea/caches
5
+ /.idea/libraries
6
+ /.idea/modules.xml
7
+ /.idea/workspace.xml
8
+ /.idea/navEditor.xml
9
+ /.idea/assetWizardSettings.xml
10
+ .DS_Store
11
+ /build
12
+ /captures
13
+ .externalNativeBuild
14
+ .cxx
15
+ local.properties
mlc-llm-main/android/MLCChat/app/.gitignore ADDED
@@ -0,0 +1 @@
 
 
1
+ /build
mlc-llm-main/android/MLCChat/app/build.gradle ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ apply plugin: 'com.android.application'
2
+
3
+ task generateJniHeaders(type: Exec, description: 'Generate JNI Headers') {
4
+ def headerPath = "${project.projectDir}/src/main/jni"
5
+ def classPath = "${project.projectDir}/../../build/tvm_home/jvm/core/target/*"
6
+ def filePath = "${project.projectDir}/../../build/tvm_home/jvm/core/src/main/java/org/apache/tvm/LibInfo.java"
7
+ commandLine "javac", "-h", headerPath, "-classpath", classPath, filePath
8
+ doLast {
9
+ file("${headerPath}/org_apache_tvm_LibInfo.h").renameTo(file("${headerPath}/org_apache_tvm_native_c_api.h"))
10
+ }
11
+ }
12
+
13
+ task copyFiles(type: Copy, description: 'Copy Sources for ndk-build') {
14
+ dependsOn "generateJniHeaders"
15
+ def ndkFilesPath = "${project.projectDir}/../../build/tvm_home/jvm/native/src/main/native"
16
+ def srcPath = "${project.projectDir}/src/main/jni/"
17
+
18
+ from "${ndkFilesPath}/org_apache_tvm_native_c_api.cc", "${ndkFilesPath}/jni_helper_func.h"
19
+ into srcPath
20
+ }
21
+
22
+ task deleteLibs(type: Delete, description: "Delete Compiled Libraries") {
23
+ dependsOn "copyFiles"
24
+ def libsPath = "${project.projectDir}/src/main/libs"
25
+ delete libsPath
26
+ }
27
+
28
+ task buildJni(type: Exec, description: 'Build JNI libs') {
29
+ dependsOn "deleteLibs"
30
+ def buildPath = "${project.projectDir}/src/main/jni"
31
+ commandLine "ndk-build", "--directory", buildPath
32
+ }
33
+
34
+ tasks.withType(JavaCompile) {
35
+ compileTask -> compileTask.dependsOn buildJni
36
+ }
37
+
38
+ android {
39
+ compileSdkVersion 33
40
+ defaultConfig {
41
+ applicationId "ai.mlc.mlcchat"
42
+ minSdkVersion 26
43
+ targetSdkVersion 33
44
+ versionCode 1
45
+ versionName "1.0"
46
+ testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
47
+ ndk {
48
+ abiFilters 'arm64-v8a'
49
+ }
50
+ }
51
+ buildTypes {
52
+ release {
53
+ minifyEnabled false
54
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
55
+ }
56
+ }
57
+ sourceSets {
58
+ main {
59
+ jni.srcDirs = []
60
+ jniLibs.srcDirs = ['src/main/libs']
61
+ }
62
+ }
63
+ namespace 'ai.mlc.mlcchat'
64
+ ndkVersion '25.2.9519653'
65
+ }
66
+
67
+ dependencies {
68
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
69
+ implementation 'com.google.android.material:material:1.9.0'
70
+ implementation files("${project.projectDir}/../../build/tvm_home/jvm/core/target/tvm4j-core-0.0.1-SNAPSHOT.jar")
71
+ }
mlc-llm-main/android/MLCChat/app/proguard-rules.pro ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Add project specific ProGuard rules here.
2
+ # You can control the set of applied configuration files using the
3
+ # proguardFiles setting in build.gradle.
4
+ #
5
+ # For more details, see
6
+ # http://developer.android.com/guide/developing/tools/proguard.html
7
+
8
+ # If your project uses WebView with JS, uncomment the following
9
+ # and specify the fully qualified class name to the JavaScript interface
10
+ # class:
11
+ #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12
+ # public *;
13
+ #}
14
+
15
+ # Uncomment this to preserve the line number information for
16
+ # debugging stack traces.
17
+ #-keepattributes SourceFile,LineNumberTable
18
+
19
+ # If you keep the line number information, uncomment this to
20
+ # hide the original source file name.
21
+ #-renamesourcefileattribute SourceFile
mlc-llm-main/android/MLCChat/app/src/main/AndroidManifest.xml ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3
+ xmlns:tools="http://schemas.android.com/tools">
4
+
5
+ <uses-permission android:name="android.permission.INTERNET" />
6
+ <uses-permission
7
+ android:name="android.permission.WRITE_EXTERNAL_STORAGE"
8
+ android:maxSdkVersion="32"
9
+ tools:ignore="ScopedStorage" />
10
+
11
+ <application
12
+ android:allowBackup="true"
13
+ android:dataExtractionRules="@xml/data_extraction_rules"
14
+ android:fullBackupContent="@xml/backup_rules"
15
+ android:icon="@mipmap/ic_launcher"
16
+ android:label="@string/app_name"
17
+ android:roundIcon="@mipmap/ic_launcher_round"
18
+ android:supportsRtl="true"
19
+ android:theme="@style/Theme.MLCChat"
20
+ tools:targetApi="31">
21
+ <uses-native-library
22
+ android:name="libOpenCL.so"
23
+ android:required="false"/>
24
+ <activity
25
+ android:name=".MainActivity"
26
+ android:screenOrientation="portrait"
27
+ android:exported="true">
28
+ <intent-filter>
29
+ <action android:name="android.intent.action.MAIN" />
30
+
31
+ <category android:name="android.intent.category.LAUNCHER" />
32
+ </intent-filter>
33
+ </activity>
34
+ </application>
35
+
36
+ </manifest>
mlc-llm-main/android/MLCChat/app/src/main/ic_launcher-playstore.png ADDED
mlc-llm-main/android/MLCChat/app/src/main/java/ai/mlc/mlcchat/ChatState.java ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ai.mlc.mlcchat;
2
+
3
+ import java.util.concurrent.ExecutorService;
4
+ import java.util.concurrent.Executors;
5
+
6
+ import android.content.Context;
7
+ import android.os.Handler;
8
+
9
+ public class ChatState {
10
+ private boolean resetRequested;
11
+ private boolean stopRequested;
12
+ private final ExecutorService executorService;
13
+ private final Handler handler;
14
+
15
+ private final LLMChat backend;
16
+
17
+ public ChatState(Handler h, Context c) {
18
+ resetRequested = false;
19
+ stopRequested = false;
20
+ executorService = Executors.newSingleThreadExecutor();
21
+ handler = h;
22
+ backend = new LLMChat(c);
23
+ executorService.execute(() -> {
24
+ backend.Init();
25
+ Utils.sendInitDone(h);
26
+ });
27
+ }
28
+
29
+ public void stop() {
30
+ if (isStopRequested()) return;
31
+ requestStop();
32
+ executorService.execute(this::finishStop);
33
+ }
34
+
35
+ public void reset() {
36
+ stop();
37
+ if (isResetRequested()) return;
38
+ requestReset();
39
+ executorService.execute(() -> {
40
+ backend.ResetChat();
41
+ finishReset();
42
+ Utils.sendReset(handler);
43
+ });
44
+ }
45
+
46
+ public synchronized void requestReset() {
47
+ assert !resetRequested;
48
+ resetRequested = true;
49
+ }
50
+
51
+ public synchronized void finishReset() {
52
+ assert resetRequested;
53
+ resetRequested = false;
54
+ }
55
+
56
+ public synchronized boolean isResetRequested() {
57
+ return resetRequested;
58
+ }
59
+
60
+ public synchronized void requestStop() {
61
+ assert !stopRequested;
62
+ stopRequested = true;
63
+ }
64
+
65
+ public synchronized void finishStop() {
66
+ assert stopRequested;
67
+ stopRequested = false;
68
+ }
69
+
70
+ public synchronized boolean isStopRequested() {
71
+ return stopRequested;
72
+ }
73
+
74
+ void generate(String text) {
75
+ assert !isStopRequested() && !isResetRequested();
76
+ executorService.execute(() -> Generate(text, handler));
77
+ }
78
+
79
+
80
+ void Dummy(String text, Handler handler) {
81
+ String result = "";
82
+ for (int i = 0; i < 8; ++i) {
83
+ try {
84
+ Thread.sleep(1000);
85
+ if (isStopRequested()) {
86
+ break;
87
+ }
88
+ result = result + " aba";
89
+ Utils.sendUpdateMessage(result, handler);
90
+ } catch (InterruptedException e) {
91
+ e.printStackTrace();
92
+ }
93
+ }
94
+ Utils.sendEnd("encode: 100.0 tok/s, decode: 100.0 tok/s", handler);
95
+ }
96
+
97
+ void Generate(String prompt, Handler handler) {
98
+ // System.err.println("Start generating");
99
+ backend.Encode(prompt);
100
+ // System.err.println("Encoding " + prompt);
101
+ while (!backend.Stopped()) {
102
+ backend.Decode();
103
+ // System.err.println("[INFO] " + backend.GetMessage());
104
+ Utils.sendUpdateMessage(backend.GetMessage(), handler);
105
+ if (isStopRequested()) {
106
+ break;
107
+ }
108
+ }
109
+ String stats = backend.RuntimeStatsText();
110
+ Utils.sendEnd(stats, handler);
111
+ }
112
+
113
+ public void terminate() {
114
+ Utils.terminate(executorService);
115
+ }
116
+
117
+ }
mlc-llm-main/android/MLCChat/app/src/main/java/ai/mlc/mlcchat/Config.java ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ai.mlc.mlcchat;
2
+
3
+ public class Config {
4
+ public static final int UPD_MSG = 0;
5
+ public static final int APP_MSG = 1;
6
+ public static final int END = 2;
7
+ public static final int RESET = 3;
8
+ public static final int PARAMS_DONE = 4;
9
+ public static final int INIT_DONE = 5;
10
+ public static final String MSG_KEY = "message";
11
+ public static final String STATS_KEY = "stats";
12
+ }
mlc-llm-main/android/MLCChat/app/src/main/java/ai/mlc/mlcchat/Downloader.java ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ai.mlc.mlcchat;
2
+
3
+ import android.content.Context;
4
+ import android.os.Environment;
5
+ import android.os.Handler;
6
+
7
+ import java.io.DataInputStream;
8
+ import java.io.File;
9
+ import java.io.FileNotFoundException;
10
+ import java.io.FileOutputStream;
11
+ import java.io.IOException;
12
+ import java.io.InputStream;
13
+ import java.net.MalformedURLException;
14
+ import java.net.URL;
15
+ import java.nio.file.Files;
16
+ import java.nio.file.StandardCopyOption;
17
+ import java.util.HashMap;
18
+ import java.util.Map;
19
+ import java.util.concurrent.ExecutorService;
20
+ import java.util.concurrent.Executors;
21
+
22
+ public class Downloader {
23
+ private ExecutorService executorService;
24
+ private Handler handler;
25
+ private boolean isDownloading;
26
+
27
+ private Context context;
28
+
29
+ private HashMap<String, String> files;
30
+
31
+ public Downloader(Handler h, Context c) {
32
+ handler = h;
33
+ context = c;
34
+ executorService = Executors.newSingleThreadExecutor();
35
+ isDownloading = false;
36
+ files = new HashMap<>();
37
+ }
38
+
39
+ public synchronized void startDownload() {
40
+ assert !isDownloading;
41
+ isDownloading = true;
42
+ }
43
+
44
+ public synchronized void endDownload() {
45
+ assert isDownloading;
46
+ isDownloading = false;
47
+ }
48
+
49
+ public synchronized boolean inDownload() {
50
+ return isDownloading;
51
+ }
52
+
53
+ public void addFile(String url, String path) {
54
+ assert !inDownload();
55
+ File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), path);
56
+ if (!file.exists()) {
57
+ files.put(url, path);
58
+ }
59
+ }
60
+
61
+ public static String reportProgress(int done, int all) {
62
+ return String.format("[System] downloading [%d / %d]", done, all);
63
+ }
64
+
65
+ public void download() {
66
+ startDownload();
67
+ executorService.execute(() -> {
68
+ HashMap<String, String> filesToDownload = new HashMap<>(files);
69
+ files.clear();
70
+ int n = filesToDownload.size();
71
+ int i = 0;
72
+ if (n > 0) {
73
+ Utils.sendAppendMessage(reportProgress(i, n), handler);
74
+ }
75
+ for (Map.Entry<String, String> entry : filesToDownload.entrySet()) {
76
+ try {
77
+ File temp = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "temp");
78
+ File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), entry.getValue());
79
+ if (!file.exists()) {
80
+ URL url = new URL(entry.getKey());
81
+ InputStream inputStream = url.openStream();
82
+ DataInputStream dataInputStream =
83
+ new DataInputStream(inputStream);
84
+ byte[] buffer = new byte[1024];
85
+ int length;
86
+
87
+ FileOutputStream fileOutputStream = new FileOutputStream(temp);
88
+ while ((length = dataInputStream.read(buffer)) > 0) {
89
+ fileOutputStream.write(buffer, 0, length);
90
+ }
91
+
92
+ Files.createDirectories(file.toPath().getParent());
93
+ Files.move(temp.toPath(), file.toPath(), StandardCopyOption.ATOMIC_MOVE);
94
+ }
95
+ ++i;
96
+ Utils.sendUpdateMessage(reportProgress(i, n), handler);
97
+ } catch (IOException e) {
98
+ throw new RuntimeException(e);
99
+ }
100
+ }
101
+ endDownload();
102
+ Utils.sendParamsDone(handler);
103
+ });
104
+ }
105
+
106
+ public void terminate() {
107
+ Utils.terminate(executorService);
108
+ }
109
+ }
mlc-llm-main/android/MLCChat/app/src/main/java/ai/mlc/mlcchat/LLMChat.java ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ai.mlc.mlcchat;
2
+
3
+ import android.content.Context;
4
+ import android.os.Environment;
5
+
6
+ import org.apache.tvm.Device;
7
+ import org.apache.tvm.Function;
8
+ import org.apache.tvm.Module;
9
+
10
+ public class LLMChat {
11
+ private Function encode_func_;
12
+ private Function decode_func_;
13
+ private Function get_message_;
14
+ private Function stopped_func_;
15
+ private Function reset_chat_func_;
16
+ private Function runtime_stats_text_func_;
17
+ private Module llm_chat_;
18
+ private final Context context;
19
+
20
+ public LLMChat(Context c) {
21
+ this.context = c;
22
+ }
23
+
24
+ public void Init() {
25
+ Function systemlib_func = Function.getFunction("runtime.SystemLib");
26
+ assert systemlib_func != null;
27
+ Module lib = systemlib_func.invoke().asModule();
28
+ assert lib != null;
29
+ Function fcreate = Function.getFunction("mlc.llm_chat_create");
30
+ assert fcreate != null;
31
+ String dist_path = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
32
+ String tokenizer_path = dist_path + "/vicuna-v1-7b/tokenizer.model";
33
+ String param_path = dist_path + "/vicuna-v1-7b/params";
34
+ System.err.println("[INFO] " + tokenizer_path);
35
+ System.err.println("[INFO] " + param_path);
36
+ System.err.println("[INFO] Before LLM Chat create");
37
+ llm_chat_ = fcreate.pushArg(lib).pushArg(tokenizer_path).pushArg(param_path).pushArg(Device.opencl().deviceType).pushArg(0).invoke().asModule();
38
+ System.err.println("[INFO] LLM Chat created!");
39
+ encode_func_ = llm_chat_.getFunction("encode");
40
+ decode_func_ = llm_chat_.getFunction("decode");
41
+ get_message_ = llm_chat_.getFunction("get_message");
42
+
43
+ stopped_func_ = llm_chat_.getFunction("stopped");
44
+ reset_chat_func_ = llm_chat_.getFunction("reset_chat");
45
+
46
+ runtime_stats_text_func_ = llm_chat_.getFunction("runtime_stats_text");
47
+
48
+ assert encode_func_ != null;
49
+ assert decode_func_ != null;
50
+ assert stopped_func_ != null;
51
+ assert runtime_stats_text_func_ != null;
52
+
53
+ String model = "vicuna";
54
+ String conv_template = "vicuna_v1.1";
55
+ int max_gen_len = 512 + 256;
56
+ double temperature = 0.7;
57
+ double top_p = 0.95;
58
+ int stream_interval = 1;
59
+ int max_window_size = 512 + 256;
60
+ int mean_gen_len = 128;
61
+ double shift_fill_factor = 0.2;
62
+ llm_chat_.getFunction("init_chat").pushArg(model).pushArg(conv_template).pushArg(max_gen_len).pushArg(temperature).pushArg(top_p).pushArg(stream_interval).pushArg(max_window_size).pushArg(mean_gen_len).pushArg(shift_fill_factor).invoke();
63
+
64
+ systemlib_func.release();
65
+ lib.release();
66
+ fcreate.release();
67
+
68
+ System.err.println("[INFO] Init done");
69
+ }
70
+ public void Evaluate() {
71
+ llm_chat_.getFunction("evaluate").invoke();
72
+ }
73
+
74
+ public String GetMessage() {
75
+ return get_message_.invoke().asString();
76
+ }
77
+
78
+ public void Encode(String prompt) {
79
+ encode_func_.pushArg(prompt).invoke();
80
+ }
81
+
82
+ public boolean Stopped() {
83
+ return stopped_func_.invoke().asLong() != 0;
84
+ }
85
+
86
+ public void Decode() {
87
+ decode_func_.invoke();
88
+ }
89
+
90
+ public String RuntimeStatsText() {
91
+ return runtime_stats_text_func_.invoke().asString();
92
+ }
93
+
94
+ public void ResetChat() {
95
+ reset_chat_func_.invoke();
96
+ }
97
+ }
mlc-llm-main/android/MLCChat/app/src/main/java/ai/mlc/mlcchat/MainActivity.java ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ai.mlc.mlcchat;
2
+
3
+ import android.app.DownloadManager;
4
+ import android.content.BroadcastReceiver;
5
+ import android.content.Context;
6
+ import android.content.Intent;
7
+ import android.content.IntentFilter;
8
+ import android.net.Uri;
9
+ import android.os.Bundle;
10
+ import android.os.Environment;
11
+ import android.os.Handler;
12
+ import android.os.Looper;
13
+ import android.os.Message;
14
+ import android.widget.Button;
15
+ import android.widget.EditText;
16
+ import android.widget.ListView;
17
+ import android.widget.TextView;
18
+
19
+ import androidx.annotation.NonNull;
20
+ import androidx.appcompat.app.AppCompatActivity;
21
+
22
+ import java.io.File;
23
+ import java.nio.file.Files;
24
+ import java.nio.file.Path;
25
+ import java.nio.file.Paths;
26
+ import java.util.concurrent.ConcurrentHashMap;
27
+
28
+ public class MainActivity extends AppCompatActivity {
29
+ private MessageAdapter messageAdapter;
30
+ private Button sendButton;
31
+ private Button resetButton;
32
+ private EditText editText;
33
+ private ListView listView;
34
+ private TextView speedText;
35
+ private Handler handler;
36
+ private ChatState chatState;
37
+ private Context context;
38
+
39
+ private Downloader downloader;
40
+
41
+ @Override
42
+ protected void onCreate(Bundle savedInstanceState) {
43
+ super.onCreate(savedInstanceState);
44
+ setContentView(R.layout.activity_main);
45
+ sendButton = findViewById(R.id.send);
46
+ resetButton = findViewById(R.id.reset);
47
+ editText = findViewById(R.id.input);
48
+ listView = findViewById(R.id.messages);
49
+ speedText = findViewById(R.id.speed);
50
+
51
+ context = getApplicationContext();
52
+
53
+ messageAdapter = new MessageAdapter(this);
54
+ listView.setAdapter(messageAdapter);
55
+ handler = new Handler(Looper.getMainLooper()) {
56
+ @Override
57
+ public void handleMessage(@NonNull Message msg) {
58
+ super.handleMessage(msg);
59
+ Bundle bundle = msg.getData();
60
+ switch (msg.what) {
61
+ case Config.INIT_DONE:
62
+ assert messageAdapter.isBotLast();
63
+ updateMessage(new MessageData(MessageRole.BOT, "[System] Ready to chat"));
64
+ resumeSend();
65
+ resumeReset();
66
+ break;
67
+ case Config.UPD_MSG:
68
+ assert messageAdapter.isBotLast();
69
+ updateMessage(new MessageData(MessageRole.BOT, bundle.getString(Config.MSG_KEY)));
70
+ break;
71
+ case Config.APP_MSG:
72
+ appendMessage(new MessageData(MessageRole.BOT, bundle.getString(Config.MSG_KEY)));
73
+ break;
74
+ case Config.END:
75
+ speedText.setText(bundle.getString(Config.STATS_KEY));
76
+ resumeSend();
77
+ break;
78
+ case Config.PARAMS_DONE:
79
+ init();
80
+ break;
81
+ case Config.RESET:
82
+ reset();
83
+ break;
84
+ }
85
+ }
86
+ };
87
+ // System starting: freeze send and reset
88
+ freezeSend();
89
+ freezeReset();
90
+ // Prepare tokenizer and model params
91
+ downloader = new Downloader(handler, context);
92
+ prepareParams();
93
+ }
94
+
95
+ private void init() {
96
+ // Follow up after param is confirmed
97
+ // Chat state will initialize in another thread
98
+ appendMessage(new MessageData(MessageRole.BOT, "[System] Initializing..."));
99
+ chatState = new ChatState(handler, context);
100
+
101
+ sendButton.setOnClickListener(v -> {
102
+ String message = freezeSend();
103
+ appendMessage(new MessageData(MessageRole.USER, message));
104
+ appendMessage(new MessageData(MessageRole.BOT, ""));
105
+ chatState.generate(message);
106
+ });
107
+ resetButton.setOnClickListener(v -> {
108
+ freezeSend();
109
+ freezeReset();
110
+ chatState.reset();
111
+ });
112
+ }
113
+
114
+ private void prepareParams() {
115
+ appendMessage(new MessageData(MessageRole.BOT, "[System] Preparing Parameters..."));
116
+ String model_name = "vicuna-v1-7b";
117
+ String base_url = "https://huggingface.co/mlc-ai/demo-vicuna-v1-7b-int4/resolve/main";
118
+ downloader.addFile(base_url + "/tokenizer.model", model_name + "/tokenizer.model");
119
+ downloader.addFile(base_url + "/float16/ndarray-cache.json", model_name + "/params/ndarray-cache.json");
120
+ for (int i = 0; i <= 131; ++i) {
121
+ String param_name = "params_shard_" + i + ".bin";
122
+ downloader.addFile(base_url + "/float16/" + param_name, model_name + "/params/" + param_name);
123
+ }
124
+ downloader.download();
125
+ }
126
+
127
+
128
+ private String freezeSend() {
129
+ String text = editText.getText().toString();
130
+ editText.getText().clear();
131
+ editText.setEnabled(false);
132
+ sendButton.setEnabled(false);
133
+ sendButton.setAlpha((float) 0.1);
134
+ return text;
135
+ }
136
+
137
+ private void resumeSend() {
138
+ sendButton.setEnabled(true);
139
+ sendButton.setAlpha((float) 1.0);
140
+ editText.setEnabled(true);
141
+ }
142
+
143
+ private void freezeReset() {
144
+ resetButton.setEnabled(false);
145
+ }
146
+
147
+ private void resumeReset() {
148
+ resetButton.setEnabled(true);
149
+ }
150
+
151
+ @Override
152
+ protected void onRestart() {
153
+ super.onRestart();
154
+ }
155
+
156
+ @Override
157
+ protected void onDestroy() {
158
+ super.onDestroy();
159
+ chatState.terminate();
160
+ downloader.terminate();
161
+ }
162
+
163
+ private void appendMessage(MessageData messageData) {
164
+ messageAdapter.appendMessage(messageData);
165
+ }
166
+
167
+ private void updateMessage(MessageData messageData) {
168
+ messageAdapter.updateMessage(messageData);
169
+ }
170
+
171
+ private void reset() {
172
+ resumeSend();
173
+ editText.getText().clear();
174
+ messageAdapter.reset();
175
+ resumeReset();
176
+ }
177
+
178
+ }
mlc-llm-main/android/MLCChat/app/src/main/java/ai/mlc/mlcchat/MessageAdapter.java ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ai.mlc.mlcchat;
2
+
3
+ import android.content.Context;
4
+ import android.view.LayoutInflater;
5
+ import android.view.View;
6
+ import android.view.ViewGroup;
7
+ import android.widget.BaseAdapter;
8
+ import android.widget.TextView;
9
+
10
+ import java.util.ArrayList;
11
+ import java.util.List;
12
+
13
+ public class MessageAdapter extends BaseAdapter {
14
+ private List<MessageData> messages;
15
+ private Context context;
16
+
17
+ public MessageAdapter(Context c) {
18
+ super();
19
+ context = c;
20
+ messages = new ArrayList<MessageData>();
21
+ }
22
+
23
+ public void appendMessage(MessageData m) {
24
+ messages.add(m);
25
+ notifyDataSetChanged();
26
+ }
27
+
28
+ public void updateMessage(MessageData m) {
29
+ messages.set(messages.size() - 1, m);
30
+ notifyDataSetChanged();
31
+ }
32
+
33
+ public boolean isBotLast() {
34
+ return messages.get(messages.size() - 1).isBot();
35
+ }
36
+
37
+ public int size() {
38
+ return messages.size();
39
+ }
40
+
41
+ public void reset() {
42
+ messages.clear();
43
+ notifyDataSetChanged();
44
+ }
45
+
46
+ @Override
47
+ public int getCount() {
48
+ return messages.size();
49
+ }
50
+
51
+ @Override
52
+ public Object getItem(int position) {
53
+ return messages.get(position);
54
+ }
55
+
56
+ @Override
57
+ public long getItemId(int position) {
58
+ return position;
59
+ }
60
+
61
+ @Override
62
+ public View getView(int position, View convertView, ViewGroup parent) {
63
+ MessageViewHolder holder = new MessageViewHolder();
64
+ LayoutInflater inflater = LayoutInflater.from(context);
65
+ MessageData chatMessage = messages.get(position);
66
+ if (chatMessage.isBot()) {
67
+ convertView = inflater.inflate(R.layout.bot_message, null);
68
+ holder.textView = convertView.findViewById(R.id.bot_message);
69
+ holder.textView.setText(chatMessage.getText());
70
+ convertView.setTag(holder);
71
+ } else {
72
+ convertView = inflater.inflate(R.layout.user_message, null);
73
+ holder.textView = convertView.findViewById(R.id.user_message);
74
+ holder.textView.setText(chatMessage.getText());
75
+ convertView.setTag(holder);
76
+ }
77
+ return convertView;
78
+ }
79
+
80
+ static class MessageViewHolder {
81
+ public TextView textView;
82
+ }
83
+ }
mlc-llm-main/android/MLCChat/app/src/main/java/ai/mlc/mlcchat/MessageData.java ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ai.mlc.mlcchat;
2
+
3
+ import androidx.annotation.NonNull;
4
+
5
+ enum MessageRole {
6
+ BOT, USER
7
+ }
8
+
9
+ public class MessageData {
10
+
11
+ private final MessageRole messageRole;
12
+ private final String text;
13
+
14
+ public MessageData(MessageRole r, String t) {
15
+ messageRole = r;
16
+ text = t;
17
+ }
18
+
19
+ public boolean isBot() {
20
+ return messageRole == MessageRole.BOT;
21
+ }
22
+
23
+ public String getText() {
24
+ return text;
25
+ }
26
+ }
mlc-llm-main/android/MLCChat/app/src/main/java/ai/mlc/mlcchat/Utils.java ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package ai.mlc.mlcchat;
2
+
3
+ import android.os.Bundle;
4
+ import android.os.Handler;
5
+ import android.os.Message;
6
+
7
+ import java.util.concurrent.ExecutorService;
8
+ import java.util.concurrent.TimeUnit;
9
+
10
+ public class Utils {
11
+ public static void sendUpdateMessage(String text, Handler handler) {
12
+ Bundle bundle = new Bundle();
13
+ bundle.putString(Config.MSG_KEY, text);
14
+ Message message = new Message();
15
+ message.setData(bundle);
16
+ message.what = Config.UPD_MSG;
17
+ handler.sendMessage(message);
18
+ }
19
+
20
+ public static void sendAppendMessage(String text, Handler handler) {
21
+ Bundle bundle = new Bundle();
22
+ bundle.putString(Config.MSG_KEY, text);
23
+ Message message = new Message();
24
+ message.setData(bundle);
25
+ message.what = Config.APP_MSG;
26
+ handler.sendMessage(message);
27
+ }
28
+
29
+ public static void sendEnd(String stats, Handler handler) {
30
+ Bundle bundle = new Bundle();
31
+ bundle.putString(Config.STATS_KEY, stats);
32
+ Message message = new Message();
33
+ message.setData(bundle);
34
+ message.what = Config.END;
35
+ handler.sendMessage(message);
36
+ }
37
+
38
+ public static void sendReset(Handler handler) {
39
+ Message message = new Message();
40
+ message.what = Config.RESET;
41
+ handler.sendMessage(message);
42
+ }
43
+
44
+ public static void sendInitDone(Handler handler) {
45
+ Message message = new Message();
46
+ message.what = Config.INIT_DONE;
47
+ handler.sendMessage(message);
48
+ }
49
+
50
+ public static void sendParamsDone(Handler handler) {
51
+ Message message = new Message();
52
+ message.what = Config.PARAMS_DONE;
53
+ handler.sendMessage(message);
54
+ }
55
+
56
+ public static void terminate(ExecutorService executorService) {
57
+ executorService.shutdown(); // Disable new tasks from being submitted
58
+ try {
59
+ // Wait a while for existing tasks to terminate
60
+ if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
61
+ executorService.shutdownNow(); // Cancel currently executing tasks
62
+ // Wait a while for tasks to respond to being cancelled
63
+ if (!executorService.awaitTermination(60, TimeUnit.SECONDS))
64
+ System.err.println("Pool did not terminate");
65
+ }
66
+ } catch (InterruptedException ie) {
67
+ // (Re-)Cancel if current thread also interrupted
68
+ executorService.shutdownNow();
69
+ // Preserve interrupt status
70
+ Thread.currentThread().interrupt();
71
+ }
72
+ }
73
+ }
mlc-llm-main/android/MLCChat/app/src/main/jni/Android.mk ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Licensed to the Apache Software Foundation (ASF) under one
2
+ # or more contributor license agreements. See the NOTICE file
3
+ # distributed with this work for additional information
4
+ # regarding copyright ownership. The ASF licenses this file
5
+ # to you under the Apache License, Version 2.0 (the
6
+ # "License"); you may not use this file except in compliance
7
+ # with the License. You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
18
+ LOCAL_PATH := $(call my-dir)
19
+ MY_PATH := $(abspath $(LOCAL_PATH))
20
+ LIB_PATH := $(MY_PATH)/../../../../../build/lib
21
+ TVM_HOME := $(MY_PATH)/../../../../../build/tvm_home
22
+
23
+ #####################################################
24
+
25
+ include $(CLEAR_VARS)
26
+ LOCAL_MODULE := local_mlc_llm
27
+ LOCAL_SRC_FILES := $(LIB_PATH)/libmlc_llm.a
28
+ include $(PREBUILT_STATIC_LIBRARY)
29
+
30
+ #####################################################
31
+
32
+ include $(CLEAR_VARS)
33
+ LOCAL_MODULE := local_sentencepiece
34
+ LOCAL_SRC_FILES := $(LIB_PATH)/libsentencepiece.a
35
+ include $(PREBUILT_STATIC_LIBRARY)
36
+
37
+ #####################################################
38
+
39
+ include $(CLEAR_VARS)
40
+ LOCAL_MODULE := local_tokenizers_cpp
41
+ LOCAL_SRC_FILES := $(LIB_PATH)/libtokenizers_cpp.a
42
+ include $(PREBUILT_STATIC_LIBRARY)
43
+
44
+ #####################################################
45
+
46
+ include $(CLEAR_VARS)
47
+ LOCAL_MODULE := local_tvm_runtime
48
+ LOCAL_SRC_FILES := $(LIB_PATH)/libtvm_runtime.a
49
+ include $(PREBUILT_STATIC_LIBRARY)
50
+
51
+ #####################################################
52
+
53
+ include $(CLEAR_VARS)
54
+ LOCAL_MODULE := local_model_android
55
+ LOCAL_SRC_FILES := $(LIB_PATH)/libmodel_android.a
56
+ include $(PREBUILT_STATIC_LIBRARY)
57
+
58
+ #####################################################
59
+
60
+ include $(CLEAR_VARS)
61
+ LOCAL_MODULE = tvm4j_runtime_packed
62
+ LOCAL_SRC_FILES := org_apache_tvm_native_c_api.cc
63
+ LOCAL_LDFLAGS := -L$(SYSROOT)/usr/lib/ -llog -pthread -ldl -lm
64
+ LOCAL_C_INCLUDES := $(TVM_HOME)/include \
65
+ $(TVM_HOME)/3rdparty/dlpack/include \
66
+ $(TVM_HOME)/3rdparty/dmlc-core/include \
67
+ $(MY_PATH)
68
+ # LOCAL_C_FLAGS := -static
69
+
70
+ LOCAL_WHOLE_STATIC_LIBRARIES := local_mlc_llm local_tvm_runtime local_model_android
71
+ LOCAL_STATIC_LIBRARIES := local_sentencepiece local_tokenizers_cpp
72
+ LOCAL_CPP_FEATURES += exceptions
73
+ LOCAL_ARM_MODE := arm
74
+
75
+ include $(BUILD_SHARED_LIBRARY)
mlc-llm-main/android/MLCChat/app/src/main/jni/Application.mk ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ APP_PLATFORM := android-24
2
+ APP_ABI := arm64-v8a
3
+ APP_STL := c++_static
4
+
5
+ APP_CPPFLAGS += -DTVM_LOG_STACK_TRACE=0 -DTVM4J_ANDROID=1 -std=c++17 -Oz -frtti
mlc-llm-main/android/MLCChat/app/src/main/jni/tvm_runtime.h ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ #define DMLC_USE_LOGGING_LIBRARY <tvm/runtime/logging.h>
2
+ #define TVM_USE_LIBBACKTRACE 0
3
+
4
+ #include <dlfcn.h>
5
+ #include <dmlc/logging.h>
6
+ #include <dmlc/thread_local.h>
7
+ #include <tvm/runtime/c_runtime_api.h>
mlc-llm-main/android/MLCChat/app/src/main/res/drawable/bot_rounded_corner.xml ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <shape xmlns:android="http://schemas.android.com/apk/res/android" >
3
+ <stroke
4
+ android:width="1dp"
5
+ android:color="@color/bot_background" />
6
+
7
+ <solid android:color="@color/bot_background" />
8
+
9
+ <padding
10
+ android:left="1dp"
11
+ android:right="1dp"
12
+ android:bottom="1dp"
13
+ android:top="1dp" />
14
+
15
+ <corners android:radius="10dp" />
16
+ </shape>
mlc-llm-main/android/MLCChat/app/src/main/res/drawable/user_rounded_corner.xml ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <shape xmlns:android="http://schemas.android.com/apk/res/android" >
3
+ <stroke
4
+ android:width="1dp"
5
+ android:color="@color/material_dynamic_primary80" />
6
+
7
+ <solid android:color="@color/material_dynamic_primary80" />
8
+
9
+ <padding
10
+ android:left="1dp"
11
+ android:right="1dp"
12
+ android:bottom="1dp"
13
+ android:top="1dp" />
14
+
15
+ <corners android:radius="10dp" />
16
+ </shape>
mlc-llm-main/android/MLCChat/app/src/main/res/layout/activity_main.xml ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
+ xmlns:app="http://schemas.android.com/apk/res-auto"
4
+ xmlns:tools="http://schemas.android.com/tools"
5
+ android:layout_width="match_parent"
6
+ android:layout_height="match_parent"
7
+ tools:context=".MainActivity">
8
+
9
+ <com.google.android.material.appbar.MaterialToolbar
10
+ android:id="@+id/toolbar"
11
+ android:layout_width="match_parent"
12
+ android:layout_height="wrap_content"
13
+ android:background="?attr/colorPrimary"
14
+ android:minHeight="?attr/actionBarSize"
15
+ android:theme="?attr/actionBarTheme"
16
+ app:layout_constraintBottom_toTopOf="@+id/speed"
17
+ app:layout_constraintEnd_toEndOf="parent"
18
+ app:layout_constraintStart_toStartOf="parent"
19
+ app:layout_constraintTop_toTopOf="parent">
20
+
21
+ <androidx.appcompat.widget.AppCompatTextView
22
+ android:layout_width="wrap_content"
23
+ android:layout_height="match_parent"
24
+ android:text="MLC Chat"
25
+ android:textColor="@color/design_default_color_on_primary"
26
+ android:layout_gravity="center"
27
+ android:textAppearance="@style/TextAppearance.Material3.HeadlineMedium" />
28
+
29
+ <androidx.appcompat.widget.AppCompatButton
30
+ style="@style/Widget.AppCompat.Button.Borderless.Colored"
31
+ android:id="@+id/reset"
32
+ android:layout_width="wrap_content"
33
+ android:layout_height="match_parent"
34
+ android:text="reset"
35
+ android:textColor="@color/design_default_color_on_primary"
36
+ android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall"
37
+ android:layout_marginEnd="5dp"
38
+ android:layout_gravity="end" />
39
+
40
+ </com.google.android.material.appbar.MaterialToolbar>
41
+
42
+ <androidx.appcompat.widget.AppCompatTextView
43
+ android:id="@+id/speed"
44
+ android:layout_width="match_parent"
45
+ android:layout_height="wrap_content"
46
+ android:textAlignment="center"
47
+ app:layout_constraintBottom_toTopOf="@id/messages"
48
+ app:layout_constraintEnd_toEndOf="parent"
49
+ app:layout_constraintStart_toStartOf="parent"
50
+ app:layout_constraintTop_toBottomOf="@id/toolbar" />
51
+
52
+
53
+ <androidx.appcompat.widget.AppCompatEditText
54
+ android:id="@+id/input"
55
+ android:layout_width="0dp"
56
+ android:layout_height="wrap_content"
57
+ android:layout_marginStart="5dp"
58
+ android:layout_marginEnd="5dp"
59
+ android:layout_marginBottom="5dp"
60
+ android:hint="Inputs..."
61
+ android:inputType="textMultiLine"
62
+ android:textAppearance="@style/TextAppearance.AppCompat.Small"
63
+ app:layout_constraintBottom_toBottomOf="parent"
64
+ app:layout_constraintEnd_toStartOf="@+id/send"
65
+ app:layout_constraintStart_toStartOf="parent" />
66
+
67
+ <androidx.appcompat.widget.AppCompatButton
68
+ android:id="@+id/send"
69
+ android:layout_width="wrap_content"
70
+ android:layout_height="wrap_content"
71
+ android:layout_marginTop="5dp"
72
+ android:layout_marginBottom="5dp"
73
+ android:layout_marginStart="5dp"
74
+ android:layout_marginEnd="5dp"
75
+ android:text="Send"
76
+ android:textAppearance="@style/TextAppearance.Material3.SearchBar"
77
+ app:layout_constraintBottom_toBottomOf="parent"
78
+ app:layout_constraintEnd_toEndOf="parent"
79
+ app:layout_constraintStart_toEndOf="@+id/input"
80
+ app:layout_constraintTop_toBottomOf="@+id/messages" />
81
+
82
+ <ListView
83
+ android:id="@+id/messages"
84
+ android:layout_width="match_parent"
85
+ android:layout_height="0dp"
86
+ android:divider="@null"
87
+ android:stackFromBottom="true"
88
+ android:transcriptMode="normal"
89
+ app:layout_constraintTop_toBottomOf="@id/speed"
90
+ app:layout_constraintBottom_toTopOf="@id/send" />
91
+
92
+ </androidx.constraintlayout.widget.ConstraintLayout>
mlc-llm-main/android/MLCChat/app/src/main/res/layout/bot_message.xml ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
+ xmlns:app="http://schemas.android.com/apk/res-auto"
4
+ xmlns:tools="http://schemas.android.com/tools"
5
+ android:layout_width="match_parent"
6
+ android:layout_height="match_parent"
7
+ android:layout_marginEnd="50dp"
8
+ android:orientation="vertical">
9
+
10
+ <androidx.appcompat.widget.AppCompatTextView
11
+ android:id="@+id/bot_message"
12
+ android:layout_width="wrap_content"
13
+ android:layout_height="wrap_content"
14
+ android:layout_margin="5dp"
15
+ android:maxWidth="300dp"
16
+ android:background="@drawable/bot_rounded_corner"
17
+ android:gravity="start"
18
+ android:padding="10dp"
19
+ android:text="aaa"
20
+ android:textColor="#FFFFFF"
21
+ android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
22
+ app:layout_constraintBottom_toBottomOf="parent"
23
+ app:layout_constraintEnd_toEndOf="parent"
24
+ app:layout_constraintHorizontal_bias="0.0"
25
+ app:layout_constraintStart_toStartOf="parent"
26
+ app:layout_constraintTop_toTopOf="parent"
27
+ app:layout_constraintVertical_bias="0.0" />
28
+
29
+
30
+ </androidx.constraintlayout.widget.ConstraintLayout>
mlc-llm-main/android/MLCChat/app/src/main/res/layout/user_message.xml ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
+ xmlns:app="http://schemas.android.com/apk/res-auto"
4
+ xmlns:tools="http://schemas.android.com/tools"
5
+ android:layout_width="match_parent"
6
+ android:layout_height="match_parent"
7
+ android:layout_marginStart="50dp"
8
+ android:orientation="vertical">
9
+
10
+ <androidx.appcompat.widget.AppCompatTextView
11
+ android:id="@+id/user_message"
12
+ android:layout_width="wrap_content"
13
+ android:layout_height="wrap_content"
14
+ android:layout_margin="5dp"
15
+ android:maxWidth="300dp"
16
+ android:gravity="start"
17
+ android:padding="10dp"
18
+ android:text="aaa"
19
+ android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
20
+ android:background="@drawable/user_rounded_corner"
21
+ android:textColor="@color/design_default_color_on_primary"
22
+ app:layout_constraintBottom_toBottomOf="parent"
23
+ app:layout_constraintEnd_toEndOf="parent"
24
+ app:layout_constraintHorizontal_bias="1.0"
25
+ app:layout_constraintStart_toStartOf="parent"
26
+ app:layout_constraintTop_toTopOf="parent"
27
+ app:layout_constraintVertical_bias="0.0" />
28
+
29
+
30
+ </androidx.constraintlayout.widget.ConstraintLayout>
mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
3
+ <background android:drawable="@color/ic_launcher_background"/>
4
+ <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
5
+ </adaptive-icon>
mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
3
+ <background android:drawable="@color/ic_launcher_background"/>
4
+ <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
5
+ </adaptive-icon>
mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-hdpi/ic_launcher.png ADDED
mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png ADDED
mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-hdpi/ic_launcher_round.png ADDED
mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-mdpi/ic_launcher.png ADDED
mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png ADDED
mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-mdpi/ic_launcher_round.png ADDED
mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-xhdpi/ic_launcher.png ADDED
mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png ADDED
mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png ADDED
mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-xxhdpi/ic_launcher.png ADDED
mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png ADDED
mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png ADDED
mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png ADDED
mlc-llm-main/android/MLCChat/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png ADDED