From 559d2ce49323deb2480a24291d19be8230fc293b Mon Sep 17 00:00:00 2001 From: zhouwg <6889919+zhouwg@users.noreply.github.com> Date: Tue, 26 Mar 2024 19:12:29 +0800 Subject: [PATCH] llamacpp:integrate ggml's excellent and amazing llama.cpp to kantv (#104) --- README.md | 42 +- build/envsetup.sh | 1 + .../java/org/ggml/whispercpp/whispercpp.java | 57 +- .../ui/fragment/ASRResearchFragment.java | 8 +- .../ui/fragment/LLMResearchFragment.java | 226 +- .../src/main/res/drawable/llamacpp_logo.png | Bin 31778 -> 18044 bytes .../src/main/res/drawable/textview_border.xml | 17 + .../src/main/res/layout/fragment_asr.xml | 2 +- .../src/main/res/layout/fragment_llm.xml | 30 +- external/.gitignore | 1 - external/whispercpp/CMakeLists.txt | 13 +- external/whispercpp/ggml-alloc.c | 19 +- external/whispercpp/ggml-backend-impl.h | 5 + external/whispercpp/ggml-backend.c | 280 +- external/whispercpp/ggml-quants.c | 40 +- external/whispercpp/ggml.c | 215 +- external/whispercpp/jni/common.cpp | 2604 + external/whispercpp/jni/common.h | 318 + external/whispercpp/jni/grammar-parser.cpp | 440 + external/whispercpp/jni/grammar-parser.h | 29 + external/whispercpp/jni/sampling.cpp | 354 + external/whispercpp/jni/sampling.h | 147 + .../whispercpp/jni/whispercpp-jni-impl.cpp | 630 +- external/whispercpp/jni/whispercpp-jni.c | 71 +- external/whispercpp/jni/whispercpp-jni.h | 5 + external/whispercpp/llamacpp/.gitignore | 105 + external/whispercpp/llamacpp/.gitmodules | 3 + external/whispercpp/llamacpp/CMakeLists.txt | 1290 + external/whispercpp/llamacpp/LICENSE | 21 + external/whispercpp/llamacpp/Makefile | 969 + external/whispercpp/llamacpp/README-sycl.md | 599 + external/whispercpp/llamacpp/README.md | 1103 + .../whispercpp/llamacpp/cmake/FindSIMD.cmake | 100 + .../whispercpp/llamacpp/common/CMakeLists.txt | 89 + .../whispercpp/llamacpp/common/base64.hpp | 392 + .../whispercpp/llamacpp/common/common.cpp | 2771 + external/whispercpp/llamacpp/common/common.h | 317 + .../whispercpp/llamacpp/common/console.cpp | 501 + external/whispercpp/llamacpp/common/console.h | 19 + .../llamacpp/common/grammar-parser.cpp | 440 + .../llamacpp/common/grammar-parser.h | 29 + .../common/json-schema-to-grammar.cpp | 721 + .../llamacpp/common/json-schema-to-grammar.h | 4 + external/whispercpp/llamacpp/common/json.hpp | 24766 ++++++++ external/whispercpp/llamacpp/common/log.h | 724 + .../llamacpp/common/ngram-cache.cpp | 282 + .../whispercpp/llamacpp/common/ngram-cache.h | 94 + .../whispercpp/llamacpp/common/sampling.cpp | 353 + .../whispercpp/llamacpp/common/sampling.h | 147 + .../whispercpp/llamacpp/common/stb_image.h | 8396 +++ external/whispercpp/llamacpp/common/train.cpp | 1513 + external/whispercpp/llamacpp/common/train.h | 233 + .../examples/baby-llama/CMakeLists.txt | 5 + .../examples/baby-llama/baby-llama.cpp | 1640 + .../examples/benchmark/CMakeLists.txt | 6 + .../examples/benchmark/benchmark-matmult.cpp | 275 + .../llamacpp/examples/imatrix/CMakeLists.txt | 5 + .../llamacpp/examples/imatrix/README.md | 32 + .../llamacpp/examples/imatrix/imatrix.cpp | 643 + .../examples/llama-bench/CMakeLists.txt | 5 + .../llamacpp/examples/llama-bench/README.md | 278 + .../examples/llama-bench/llama-bench.cpp | 1286 + .../llamacpp/examples/main/CMakeLists.txt | 5 + .../llamacpp/examples/main/README.md | 323 + .../llamacpp/examples/main/main.cpp | 956 + .../llamacpp/examples/simple/CMakeLists.txt | 5 + .../llamacpp/examples/simple/README.md | 21 + .../llamacpp/examples/simple/simple.cpp | 183 + external/whispercpp/llamacpp/ggml-alloc.c | 980 + .../whispercpp/{ => llamacpp}/ggml-alloc.h | 0 .../whispercpp/llamacpp/ggml-backend-impl.h | 141 + external/whispercpp/llamacpp/ggml-backend.c | 2095 + .../whispercpp/{ => llamacpp}/ggml-backend.h | 8 +- external/whispercpp/llamacpp/ggml-common.h | 1830 + external/whispercpp/llamacpp/ggml-cuda.cu | 2841 + external/whispercpp/llamacpp/ggml-cuda.h | 43 + external/whispercpp/llamacpp/ggml-cuda/acc.cu | 47 + .../whispercpp/llamacpp/ggml-cuda/acc.cuh | 5 + .../whispercpp/llamacpp/ggml-cuda/alibi.cu | 63 + .../whispercpp/llamacpp/ggml-cuda/alibi.cuh | 5 + .../whispercpp/llamacpp/ggml-cuda/arange.cu | 34 + .../whispercpp/llamacpp/ggml-cuda/arange.cuh | 5 + .../whispercpp/llamacpp/ggml-cuda/argsort.cu | 77 + .../whispercpp/llamacpp/ggml-cuda/argsort.cuh | 3 + .../whispercpp/llamacpp/ggml-cuda/binbcast.cu | 236 + .../llamacpp/ggml-cuda/binbcast.cuh | 6 + .../whispercpp/llamacpp/ggml-cuda/clamp.cu | 35 + .../whispercpp/llamacpp/ggml-cuda/clamp.cuh | 5 + .../whispercpp/llamacpp/ggml-cuda/common.cuh | 550 + .../whispercpp/llamacpp/ggml-cuda/concat.cu | 49 + .../whispercpp/llamacpp/ggml-cuda/concat.cuh | 5 + .../whispercpp/llamacpp/ggml-cuda/convert.cu | 783 + .../whispercpp/llamacpp/ggml-cuda/convert.cuh | 13 + external/whispercpp/llamacpp/ggml-cuda/cpy.cu | 461 + .../whispercpp/llamacpp/ggml-cuda/cpy.cuh | 7 + .../llamacpp/ggml-cuda/dequantize.cuh | 103 + .../whispercpp/llamacpp/ggml-cuda/diagmask.cu | 40 + .../llamacpp/ggml-cuda/diagmask.cuh | 5 + .../whispercpp/llamacpp/ggml-cuda/dmmv.cu | 821 + .../whispercpp/llamacpp/ggml-cuda/dmmv.cuh | 7 + .../whispercpp/llamacpp/ggml-cuda/getrows.cu | 178 + .../whispercpp/llamacpp/ggml-cuda/getrows.cuh | 5 + .../whispercpp/llamacpp/ggml-cuda/im2col.cu | 104 + .../whispercpp/llamacpp/ggml-cuda/im2col.cuh | 5 + external/whispercpp/llamacpp/ggml-cuda/mmq.cu | 2265 + .../whispercpp/llamacpp/ggml-cuda/mmq.cuh | 9 + .../whispercpp/llamacpp/ggml-cuda/mmvq.cu | 395 + .../whispercpp/llamacpp/ggml-cuda/mmvq.cuh | 7 + .../whispercpp/llamacpp/ggml-cuda/norm.cu | 215 + .../whispercpp/llamacpp/ggml-cuda/norm.cuh | 7 + external/whispercpp/llamacpp/ggml-cuda/pad.cu | 49 + .../whispercpp/llamacpp/ggml-cuda/pad.cuh | 5 + .../whispercpp/llamacpp/ggml-cuda/pool2d.cu | 94 + .../whispercpp/llamacpp/ggml-cuda/pool2d.cuh | 5 + .../whispercpp/llamacpp/ggml-cuda/quantize.cu | 45 + .../llamacpp/ggml-cuda/quantize.cuh | 5 + .../whispercpp/llamacpp/ggml-cuda/rope.cu | 308 + .../whispercpp/llamacpp/ggml-cuda/rope.cuh | 5 + .../whispercpp/llamacpp/ggml-cuda/scale.cu | 32 + .../whispercpp/llamacpp/ggml-cuda/scale.cuh | 5 + .../whispercpp/llamacpp/ggml-cuda/softmax.cu | 201 + .../whispercpp/llamacpp/ggml-cuda/softmax.cuh | 5 + .../whispercpp/llamacpp/ggml-cuda/sumrows.cu | 40 + .../whispercpp/llamacpp/ggml-cuda/sumrows.cuh | 3 + .../whispercpp/llamacpp/ggml-cuda/tsembd.cu | 47 + .../whispercpp/llamacpp/ggml-cuda/tsembd.cuh | 5 + .../whispercpp/llamacpp/ggml-cuda/unary.cu | 240 + .../whispercpp/llamacpp/ggml-cuda/unary.cuh | 27 + .../whispercpp/llamacpp/ggml-cuda/upscale.cu | 48 + .../whispercpp/llamacpp/ggml-cuda/upscale.cuh | 5 + .../whispercpp/llamacpp/ggml-cuda/vecdotq.cuh | 1284 + external/whispercpp/llamacpp/ggml-impl.h | 265 + external/whispercpp/llamacpp/ggml-kompute.cpp | 2002 + external/whispercpp/llamacpp/ggml-kompute.h | 46 + external/whispercpp/llamacpp/ggml-metal.h | 66 + external/whispercpp/llamacpp/ggml-metal.m | 2932 + external/whispercpp/llamacpp/ggml-metal.metal | 7140 +++ external/whispercpp/llamacpp/ggml-mpi.c | 216 + external/whispercpp/llamacpp/ggml-mpi.h | 39 + external/whispercpp/llamacpp/ggml-opencl.cpp | 2296 + external/whispercpp/llamacpp/ggml-opencl.h | 36 + external/whispercpp/llamacpp/ggml-quants.c | 12083 ++++ external/whispercpp/llamacpp/ggml-quants.h | 130 + external/whispercpp/llamacpp/ggml-sycl.cpp | 17243 ++++++ external/whispercpp/llamacpp/ggml-sycl.h | 49 + .../llamacpp/ggml-vulkan-shaders.hpp | 47589 ++++++++++++++++ external/whispercpp/llamacpp/ggml-vulkan.cpp | 6421 +++ external/whispercpp/llamacpp/ggml-vulkan.h | 40 + external/whispercpp/llamacpp/ggml.c | 21761 +++++++ external/whispercpp/{ => llamacpp}/ggml.h | 12 +- .../whispercpp/llamacpp/grammars/README.md | 91 + .../llamacpp/grammars/arithmetic.gbnf | 6 + external/whispercpp/llamacpp/grammars/c.gbnf | 42 + .../whispercpp/llamacpp/grammars/chess.gbnf | 13 + .../llamacpp/grammars/japanese.gbnf | 7 + .../whispercpp/llamacpp/grammars/json.gbnf | 25 + .../llamacpp/grammars/json_arr.gbnf | 34 + .../whispercpp/llamacpp/grammars/list.gbnf | 4 + external/whispercpp/llamacpp/llama.cpp | 15309 +++++ external/whispercpp/llamacpp/llama.h | 1008 + .../llamacpp/prompts/LLM-questions.txt | 49 + .../whispercpp/llamacpp/prompts/alpaca.txt | 1 + .../whispercpp/llamacpp/prompts/assistant.txt | 31 + .../llamacpp/prompts/chat-with-baichuan.txt | 4 + .../llamacpp/prompts/chat-with-bob.txt | 7 + .../llamacpp/prompts/chat-with-qwen.txt | 1 + .../llamacpp/prompts/chat-with-vicuna-v0.txt | 7 + .../llamacpp/prompts/chat-with-vicuna-v1.txt | 7 + external/whispercpp/llamacpp/prompts/chat.txt | 28 + .../llamacpp/prompts/dan-modified.txt | 1 + external/whispercpp/llamacpp/prompts/dan.txt | 1 + .../whispercpp/llamacpp/prompts/mnemonics.txt | 93 + .../llamacpp/prompts/parallel-questions.txt | 43 + .../llamacpp/prompts/reason-act.txt | 18 + .../llamacpp/scripts/LlamaConfig.cmake.in | 71 + .../llamacpp/scripts/check-requirements.sh | 174 + .../whispercpp/llamacpp/scripts/ci-run.sh | 50 + .../llamacpp/scripts/compare-commits.sh | 37 + .../llamacpp/scripts/compare-llama-bench.py | 374 + .../whispercpp/llamacpp/scripts/convert-gg.sh | 26 + .../llamacpp/scripts/gen-build-info-cpp.cmake | 24 + .../whispercpp/llamacpp/scripts/get-flags.mk | 38 + .../llamacpp/scripts/get-hellaswag.sh | 10 + .../whispercpp/llamacpp/scripts/get-pg.sh | 70 + .../llamacpp/scripts/get-wikitext-103.sh | 10 + .../llamacpp/scripts/get-wikitext-2.sh | 10 + .../llamacpp/scripts/get-winogrande.sh | 10 + external/whispercpp/llamacpp/scripts/hf.sh | 107 + .../whispercpp/llamacpp/scripts/pod-llama.sh | 213 + .../whispercpp/llamacpp/scripts/qnt-all.sh | 30 + .../llamacpp/scripts/run-all-perf.sh | 34 + .../llamacpp/scripts/run-all-ppl.sh | 30 + .../llamacpp/scripts/run-with-preset.py | 140 + .../whispercpp/llamacpp/scripts/server-llm.sh | 423 + .../llamacpp/scripts/sync-ggml-am.sh | 170 + .../llamacpp/scripts/sync-ggml.last | 1 + .../whispercpp/llamacpp/scripts/sync-ggml.sh | 32 + .../scripts/verify-checksum-models.py | 81 + .../llamacpp/spm-headers/ggml-alloc.h | 1 + .../llamacpp/spm-headers/ggml-backend.h | 1 + .../whispercpp/llamacpp/spm-headers/ggml.h | 1 + .../whispercpp/llamacpp/spm-headers/llama.h | 1 + external/whispercpp/llamacpp/unicode.cpp | 1672 + external/whispercpp/llamacpp/unicode.h | 26 + external/whispercpp/models/.gitignore | 1 - external/whispercpp/models/README.md | 110 - .../whispercpp/models/convert-h5-to-coreml.py | 117 - .../whispercpp/models/convert-h5-to-ggml.py | 208 - .../whispercpp/models/convert-pt-to-ggml.py | 342 - .../models/convert-whisper-to-coreml.py | 318 - .../models/convert-whisper-to-openvino.py | 60 - .../models/download-coreml-model.sh | 82 - .../whispercpp/models/download-ggml-model.cmd | 64 - .../whispercpp/models/download-ggml-model.sh | 122 - .../models/generate-coreml-interface.sh | 29 - .../models/generate-coreml-model.sh | 36 - external/whispercpp/models/ggml_to_pt.py | 109 - .../whispercpp/models/requirements-coreml.txt | 4 - .../models/requirements-openvino.txt | 2 - external/whispercpp/tests/.gitignore | 3 - external/whispercpp/tests/CMakeLists.txt | 76 - external/whispercpp/tests/en-0-ref.txt | 1 - external/whispercpp/tests/en-1-ref.txt | 1 - external/whispercpp/tests/en-2-ref.txt | 1 - external/whispercpp/tests/es-0-ref.txt | 1 - external/whispercpp/tests/run-tests.sh | 130 - external/whispercpp/tests/test-whisper.js | 58 - external/whispercpp/whisper.cpp | 2 +- 228 files changed, 214962 insertions(+), 2132 deletions(-) create mode 100644 cdeosplayer/kantv/src/main/res/drawable/textview_border.xml create mode 100644 external/whispercpp/jni/common.cpp create mode 100644 external/whispercpp/jni/common.h create mode 100644 external/whispercpp/jni/grammar-parser.cpp create mode 100644 external/whispercpp/jni/grammar-parser.h create mode 100644 external/whispercpp/jni/sampling.cpp create mode 100644 external/whispercpp/jni/sampling.h create mode 100644 external/whispercpp/llamacpp/.gitignore create mode 100644 external/whispercpp/llamacpp/.gitmodules create mode 100644 external/whispercpp/llamacpp/CMakeLists.txt create mode 100644 external/whispercpp/llamacpp/LICENSE create mode 100644 external/whispercpp/llamacpp/Makefile create mode 100644 external/whispercpp/llamacpp/README-sycl.md create mode 100644 external/whispercpp/llamacpp/README.md create mode 100644 external/whispercpp/llamacpp/cmake/FindSIMD.cmake create mode 100644 external/whispercpp/llamacpp/common/CMakeLists.txt create mode 100644 external/whispercpp/llamacpp/common/base64.hpp create mode 100644 external/whispercpp/llamacpp/common/common.cpp create mode 100644 external/whispercpp/llamacpp/common/common.h create mode 100644 external/whispercpp/llamacpp/common/console.cpp create mode 100644 external/whispercpp/llamacpp/common/console.h create mode 100644 external/whispercpp/llamacpp/common/grammar-parser.cpp create mode 100644 external/whispercpp/llamacpp/common/grammar-parser.h create mode 100644 external/whispercpp/llamacpp/common/json-schema-to-grammar.cpp create mode 100644 external/whispercpp/llamacpp/common/json-schema-to-grammar.h create mode 100644 external/whispercpp/llamacpp/common/json.hpp create mode 100644 external/whispercpp/llamacpp/common/log.h create mode 100644 external/whispercpp/llamacpp/common/ngram-cache.cpp create mode 100644 external/whispercpp/llamacpp/common/ngram-cache.h create mode 100644 external/whispercpp/llamacpp/common/sampling.cpp create mode 100644 external/whispercpp/llamacpp/common/sampling.h create mode 100644 external/whispercpp/llamacpp/common/stb_image.h create mode 100644 external/whispercpp/llamacpp/common/train.cpp create mode 100644 external/whispercpp/llamacpp/common/train.h create mode 100644 external/whispercpp/llamacpp/examples/baby-llama/CMakeLists.txt create mode 100644 external/whispercpp/llamacpp/examples/baby-llama/baby-llama.cpp create mode 100644 external/whispercpp/llamacpp/examples/benchmark/CMakeLists.txt create mode 100644 external/whispercpp/llamacpp/examples/benchmark/benchmark-matmult.cpp create mode 100644 external/whispercpp/llamacpp/examples/imatrix/CMakeLists.txt create mode 100644 external/whispercpp/llamacpp/examples/imatrix/README.md create mode 100644 external/whispercpp/llamacpp/examples/imatrix/imatrix.cpp create mode 100644 external/whispercpp/llamacpp/examples/llama-bench/CMakeLists.txt create mode 100644 external/whispercpp/llamacpp/examples/llama-bench/README.md create mode 100644 external/whispercpp/llamacpp/examples/llama-bench/llama-bench.cpp create mode 100644 external/whispercpp/llamacpp/examples/main/CMakeLists.txt create mode 100644 external/whispercpp/llamacpp/examples/main/README.md create mode 100644 external/whispercpp/llamacpp/examples/main/main.cpp create mode 100644 external/whispercpp/llamacpp/examples/simple/CMakeLists.txt create mode 100644 external/whispercpp/llamacpp/examples/simple/README.md create mode 100644 external/whispercpp/llamacpp/examples/simple/simple.cpp create mode 100644 external/whispercpp/llamacpp/ggml-alloc.c rename external/whispercpp/{ => llamacpp}/ggml-alloc.h (100%) create mode 100644 external/whispercpp/llamacpp/ggml-backend-impl.h create mode 100644 external/whispercpp/llamacpp/ggml-backend.c rename external/whispercpp/{ => llamacpp}/ggml-backend.h (96%) create mode 100644 external/whispercpp/llamacpp/ggml-common.h create mode 100644 external/whispercpp/llamacpp/ggml-cuda.cu create mode 100644 external/whispercpp/llamacpp/ggml-cuda.h create mode 100644 external/whispercpp/llamacpp/ggml-cuda/acc.cu create mode 100644 external/whispercpp/llamacpp/ggml-cuda/acc.cuh create mode 100644 external/whispercpp/llamacpp/ggml-cuda/alibi.cu create mode 100644 external/whispercpp/llamacpp/ggml-cuda/alibi.cuh create mode 100644 external/whispercpp/llamacpp/ggml-cuda/arange.cu create mode 100644 external/whispercpp/llamacpp/ggml-cuda/arange.cuh create mode 100644 external/whispercpp/llamacpp/ggml-cuda/argsort.cu create mode 100644 external/whispercpp/llamacpp/ggml-cuda/argsort.cuh create mode 100644 external/whispercpp/llamacpp/ggml-cuda/binbcast.cu create mode 100644 external/whispercpp/llamacpp/ggml-cuda/binbcast.cuh create mode 100644 external/whispercpp/llamacpp/ggml-cuda/clamp.cu create mode 100644 external/whispercpp/llamacpp/ggml-cuda/clamp.cuh create mode 100644 external/whispercpp/llamacpp/ggml-cuda/common.cuh create mode 100644 external/whispercpp/llamacpp/ggml-cuda/concat.cu create mode 100644 external/whispercpp/llamacpp/ggml-cuda/concat.cuh create mode 100644 external/whispercpp/llamacpp/ggml-cuda/convert.cu create mode 100644 external/whispercpp/llamacpp/ggml-cuda/convert.cuh create mode 100644 external/whispercpp/llamacpp/ggml-cuda/cpy.cu create mode 100644 external/whispercpp/llamacpp/ggml-cuda/cpy.cuh create mode 100644 external/whispercpp/llamacpp/ggml-cuda/dequantize.cuh create mode 100644 external/whispercpp/llamacpp/ggml-cuda/diagmask.cu create mode 100644 external/whispercpp/llamacpp/ggml-cuda/diagmask.cuh create mode 100644 external/whispercpp/llamacpp/ggml-cuda/dmmv.cu create mode 100644 external/whispercpp/llamacpp/ggml-cuda/dmmv.cuh create mode 100644 external/whispercpp/llamacpp/ggml-cuda/getrows.cu create mode 100644 external/whispercpp/llamacpp/ggml-cuda/getrows.cuh create mode 100644 external/whispercpp/llamacpp/ggml-cuda/im2col.cu create mode 100644 external/whispercpp/llamacpp/ggml-cuda/im2col.cuh create mode 100644 external/whispercpp/llamacpp/ggml-cuda/mmq.cu create mode 100644 external/whispercpp/llamacpp/ggml-cuda/mmq.cuh create mode 100644 external/whispercpp/llamacpp/ggml-cuda/mmvq.cu create mode 100644 external/whispercpp/llamacpp/ggml-cuda/mmvq.cuh create mode 100644 external/whispercpp/llamacpp/ggml-cuda/norm.cu create mode 100644 external/whispercpp/llamacpp/ggml-cuda/norm.cuh create mode 100644 external/whispercpp/llamacpp/ggml-cuda/pad.cu create mode 100644 external/whispercpp/llamacpp/ggml-cuda/pad.cuh create mode 100644 external/whispercpp/llamacpp/ggml-cuda/pool2d.cu create mode 100644 external/whispercpp/llamacpp/ggml-cuda/pool2d.cuh create mode 100644 external/whispercpp/llamacpp/ggml-cuda/quantize.cu create mode 100644 external/whispercpp/llamacpp/ggml-cuda/quantize.cuh create mode 100644 external/whispercpp/llamacpp/ggml-cuda/rope.cu create mode 100644 external/whispercpp/llamacpp/ggml-cuda/rope.cuh create mode 100644 external/whispercpp/llamacpp/ggml-cuda/scale.cu create mode 100644 external/whispercpp/llamacpp/ggml-cuda/scale.cuh create mode 100644 external/whispercpp/llamacpp/ggml-cuda/softmax.cu create mode 100644 external/whispercpp/llamacpp/ggml-cuda/softmax.cuh create mode 100644 external/whispercpp/llamacpp/ggml-cuda/sumrows.cu create mode 100644 external/whispercpp/llamacpp/ggml-cuda/sumrows.cuh create mode 100644 external/whispercpp/llamacpp/ggml-cuda/tsembd.cu create mode 100644 external/whispercpp/llamacpp/ggml-cuda/tsembd.cuh create mode 100644 external/whispercpp/llamacpp/ggml-cuda/unary.cu create mode 100644 external/whispercpp/llamacpp/ggml-cuda/unary.cuh create mode 100644 external/whispercpp/llamacpp/ggml-cuda/upscale.cu create mode 100644 external/whispercpp/llamacpp/ggml-cuda/upscale.cuh create mode 100644 external/whispercpp/llamacpp/ggml-cuda/vecdotq.cuh create mode 100644 external/whispercpp/llamacpp/ggml-impl.h create mode 100644 external/whispercpp/llamacpp/ggml-kompute.cpp create mode 100644 external/whispercpp/llamacpp/ggml-kompute.h create mode 100644 external/whispercpp/llamacpp/ggml-metal.h create mode 100644 external/whispercpp/llamacpp/ggml-metal.m create mode 100644 external/whispercpp/llamacpp/ggml-metal.metal create mode 100644 external/whispercpp/llamacpp/ggml-mpi.c create mode 100644 external/whispercpp/llamacpp/ggml-mpi.h create mode 100644 external/whispercpp/llamacpp/ggml-opencl.cpp create mode 100644 external/whispercpp/llamacpp/ggml-opencl.h create mode 100644 external/whispercpp/llamacpp/ggml-quants.c create mode 100644 external/whispercpp/llamacpp/ggml-quants.h create mode 100644 external/whispercpp/llamacpp/ggml-sycl.cpp create mode 100644 external/whispercpp/llamacpp/ggml-sycl.h create mode 100644 external/whispercpp/llamacpp/ggml-vulkan-shaders.hpp create mode 100644 external/whispercpp/llamacpp/ggml-vulkan.cpp create mode 100644 external/whispercpp/llamacpp/ggml-vulkan.h create mode 100644 external/whispercpp/llamacpp/ggml.c rename external/whispercpp/{ => llamacpp}/ggml.h (99%) create mode 100644 external/whispercpp/llamacpp/grammars/README.md create mode 100644 external/whispercpp/llamacpp/grammars/arithmetic.gbnf create mode 100644 external/whispercpp/llamacpp/grammars/c.gbnf create mode 100644 external/whispercpp/llamacpp/grammars/chess.gbnf create mode 100644 external/whispercpp/llamacpp/grammars/japanese.gbnf create mode 100644 external/whispercpp/llamacpp/grammars/json.gbnf create mode 100644 external/whispercpp/llamacpp/grammars/json_arr.gbnf create mode 100644 external/whispercpp/llamacpp/grammars/list.gbnf create mode 100644 external/whispercpp/llamacpp/llama.cpp create mode 100644 external/whispercpp/llamacpp/llama.h create mode 100644 external/whispercpp/llamacpp/prompts/LLM-questions.txt create mode 100644 external/whispercpp/llamacpp/prompts/alpaca.txt create mode 100644 external/whispercpp/llamacpp/prompts/assistant.txt create mode 100644 external/whispercpp/llamacpp/prompts/chat-with-baichuan.txt create mode 100644 external/whispercpp/llamacpp/prompts/chat-with-bob.txt create mode 100644 external/whispercpp/llamacpp/prompts/chat-with-qwen.txt create mode 100644 external/whispercpp/llamacpp/prompts/chat-with-vicuna-v0.txt create mode 100644 external/whispercpp/llamacpp/prompts/chat-with-vicuna-v1.txt create mode 100644 external/whispercpp/llamacpp/prompts/chat.txt create mode 100644 external/whispercpp/llamacpp/prompts/dan-modified.txt create mode 100644 external/whispercpp/llamacpp/prompts/dan.txt create mode 100644 external/whispercpp/llamacpp/prompts/mnemonics.txt create mode 100644 external/whispercpp/llamacpp/prompts/parallel-questions.txt create mode 100644 external/whispercpp/llamacpp/prompts/reason-act.txt create mode 100644 external/whispercpp/llamacpp/scripts/LlamaConfig.cmake.in create mode 100755 external/whispercpp/llamacpp/scripts/check-requirements.sh create mode 100755 external/whispercpp/llamacpp/scripts/ci-run.sh create mode 100755 external/whispercpp/llamacpp/scripts/compare-commits.sh create mode 100755 external/whispercpp/llamacpp/scripts/compare-llama-bench.py create mode 100755 external/whispercpp/llamacpp/scripts/convert-gg.sh create mode 100644 external/whispercpp/llamacpp/scripts/gen-build-info-cpp.cmake create mode 100644 external/whispercpp/llamacpp/scripts/get-flags.mk create mode 100755 external/whispercpp/llamacpp/scripts/get-hellaswag.sh create mode 100755 external/whispercpp/llamacpp/scripts/get-pg.sh create mode 100755 external/whispercpp/llamacpp/scripts/get-wikitext-103.sh create mode 100755 external/whispercpp/llamacpp/scripts/get-wikitext-2.sh create mode 100755 external/whispercpp/llamacpp/scripts/get-winogrande.sh create mode 100755 external/whispercpp/llamacpp/scripts/hf.sh create mode 100644 external/whispercpp/llamacpp/scripts/pod-llama.sh create mode 100755 external/whispercpp/llamacpp/scripts/qnt-all.sh create mode 100755 external/whispercpp/llamacpp/scripts/run-all-perf.sh create mode 100755 external/whispercpp/llamacpp/scripts/run-all-ppl.sh create mode 100755 external/whispercpp/llamacpp/scripts/run-with-preset.py create mode 100644 external/whispercpp/llamacpp/scripts/server-llm.sh create mode 100755 external/whispercpp/llamacpp/scripts/sync-ggml-am.sh create mode 100644 external/whispercpp/llamacpp/scripts/sync-ggml.last create mode 100755 external/whispercpp/llamacpp/scripts/sync-ggml.sh create mode 100755 external/whispercpp/llamacpp/scripts/verify-checksum-models.py create mode 120000 external/whispercpp/llamacpp/spm-headers/ggml-alloc.h create mode 120000 external/whispercpp/llamacpp/spm-headers/ggml-backend.h create mode 120000 external/whispercpp/llamacpp/spm-headers/ggml.h create mode 120000 external/whispercpp/llamacpp/spm-headers/llama.h create mode 100644 external/whispercpp/llamacpp/unicode.cpp create mode 100644 external/whispercpp/llamacpp/unicode.h delete mode 100644 external/whispercpp/models/.gitignore delete mode 100644 external/whispercpp/models/README.md delete mode 100644 external/whispercpp/models/convert-h5-to-coreml.py delete mode 100644 external/whispercpp/models/convert-h5-to-ggml.py delete mode 100644 external/whispercpp/models/convert-pt-to-ggml.py delete mode 100644 external/whispercpp/models/convert-whisper-to-coreml.py delete mode 100644 external/whispercpp/models/convert-whisper-to-openvino.py delete mode 100755 external/whispercpp/models/download-coreml-model.sh delete mode 100644 external/whispercpp/models/download-ggml-model.cmd delete mode 100755 external/whispercpp/models/download-ggml-model.sh delete mode 100755 external/whispercpp/models/generate-coreml-interface.sh delete mode 100755 external/whispercpp/models/generate-coreml-model.sh delete mode 100644 external/whispercpp/models/ggml_to_pt.py delete mode 100644 external/whispercpp/models/requirements-coreml.txt delete mode 100644 external/whispercpp/models/requirements-openvino.txt delete mode 100644 external/whispercpp/tests/.gitignore delete mode 100644 external/whispercpp/tests/CMakeLists.txt delete mode 100644 external/whispercpp/tests/en-0-ref.txt delete mode 100644 external/whispercpp/tests/en-1-ref.txt delete mode 100644 external/whispercpp/tests/en-2-ref.txt delete mode 100644 external/whispercpp/tests/es-0-ref.txt delete mode 100755 external/whispercpp/tests/run-tests.sh delete mode 100644 external/whispercpp/tests/test-whisper.js diff --git a/README.md b/README.md index c4872eb12..07b537165 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,9 @@ KanTV("Kan", aka Chinese PinYin "Kan" or Chinese HanZi "看" or English "watch/l - Record online TV to automatically generate videos (useful for short video creators to generate short video materials but pls respect IPR of original content creator/provider); record online TV's video / audio content for gather video / audio data which might be required of/useful for AI R&D activity -- ASR(Automatic Speech Recognition, a sub-filed of AI) research by the great whisper.cpp +- ASR(Automatic Speech Recognition, a subfiled of AI) research by the great whisper.cpp -- LLM(Large Language Model, a sub-filed of AI) research by the great llama.cpp +- LLM(Large Language Model, a subfiled of AI) research by the great llama.cpp - Real-time English subtitle for English online-TV(aka OTT TV) by the great & excellent & amazing whisper.cpp (PoC finished on Xiaomi 14. Xiaomi 14 or other powerful Android mobile phone is HIGHLY required/recommended for real-time subtitle feature otherwise unexpected behavior would happen) @@ -27,7 +27,7 @@ Some goals of this project are: - Well-maintained "workbench" for LLM(Large Language Model) researchers who was interested in practise state-of-the-art AI tech(like [llama.cpp](https://github.com/ggerganov/llama.cpp)) in real scenario on mobile device(Android) -- Android turn-key project for AI experts(whom mightbe not familiar with regular Android software development) focus on AI research activity, part of AI R&D activity(algorithm improvement, model training, model generation, algorithm validation, model validation, performance benchmark......) could be done by Android Studio IDE + a powerful Android phone very easily +- Android turn-key project for AI experts/researchers(whom mightbe not familiar with regular Android software development) focus on device-side AI R&D activity, part of AI R&D activity(algorithm improvement, model training, model generation, algorithm validation, model validation, performance benchmark......) could be done by Android Studio IDE + a powerful Android phone very easily ### How to build project @@ -150,24 +150,38 @@ autocmd InsertEnter * match ForbiddenWhitespace /\t\|\s\+\%#\@build/envsetup.sh accordingly before launch build + - download android-ndk-r26c to prebuilts/toolchain, skip this step if android-ndk-r26c is already exist -pay attention here and modify it accordingly if build-target is kantv-android and running Android device is NOT Xiaomi 14 +``` -(TIP: a VERY powerful Linux PC / Linux workstation is HIGHLY recommended for this step) +./build/prebuild-download.sh ``` + + - modify build/envsetup.sh accordingly before launch build + + - moidfy whispercpp/CMakeLists.txt accordingly if build-target is kantv-android and running Android device is NOT Xiaomi 14 + + +#### Build native codes + +``` + . build/envsetup.sh -(download android-ndk-r26c to prebuilts/toolchain, skip this step if android-ndk-r26c is already exist) -./build/prebuild-download.sh ``` ![Screenshot from 2024-03-21 21-41-41](https://github.com/zhouwg/kantv/assets/6889919/3e13946f-596b-44be-9716-5793ce0c7263) @@ -184,7 +198,7 @@ pay attention i TextView _txtLLMInfo; TextView _txtGGMLInfo; TextView _txtGGMLStatus; + EditText _txtUserInput; + Button _btnInference; - Button _btnBenchmark; - - - private int nThreadCounts = 1; + private int nThreadCounts = 8; private int benchmarkIndex = 0; - private String strModeName = "tiny"; private long beginTime = 0; private long endTime = 0; private long duration = 0; private String strBenchmarkInfo; + private String strUserInput = "how many days in this month?"; private AtomicBoolean isBenchmarking = new AtomicBoolean(false); private ProgressDialog mProgressDialog; + // https://huggingface.co/TheBloke/Llama-2-7B-GGUF + // https://huggingface.co/TheBloke/Llama-2-13B-GGUF + // https://huggingface.co/TheBloke/Llama-2-70B-GGUF + // https://huggingface.co/TheBloke/Llama-2-7B-Chat-GGUF - // https://huggingface.co/TheBloke/Llama-2-7B-Chat-GGUF/resolve/main/llama-2-7b-chat.Q4_K_M.gguf + // https://huggingface.co/TheBloke/Llama-2-13B-chat-GGUF + // https://huggingface.co/TheBloke/Llama-2-70B-Chat-GGUF + + //private String ggmlModelFileName = "llama-2-7b.Q4_K_M.gguf"; //4.08 GB private String ggmlModelFileName = "llama-2-7b-chat.Q4_K_M.gguf"; //4.08 GB private Context mContext; private Activity mActivity; private Settings mSettings; + private KANTVMgr mKANTVMgr = null; + private LLMResearchFragment.MyEventListener mEventListener = new LLMResearchFragment.MyEventListener(); public static LLMResearchFragment newInstance() { return new LLMResearchFragment(); @@ -138,24 +153,137 @@ public void initView() { _txtGGMLInfo = (TextView) mActivity.findViewById(R.id.ggmlInfoLLM); _txtGGMLStatus = (TextView) mActivity.findViewById(R.id.ggmlStatusLLM); + //TODO: change to voice input, and then use whisper.cpp to convert it into text + _txtUserInput = (EditText) mActivity.findViewById(R.id.txtUserInput); + + _btnInference = (Button) mActivity.findViewById(R.id.btnInference); + _txtLLMInfo.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null); + _txtLLMInfo.setMovementMethod(ScrollingMovementMethod.getInstance()); displayFileStatus(CDEUtils.getDataPath() + ggmlModelFileName); - CDELog.j(TAG, "load LLM model"); + try { + CDELibraryLoader.load("whispercpp"); + CDELog.j(TAG, "cpu core counts:" + whispercpp.get_cpu_core_counts()); + } catch (Exception e) { + CDELog.j(TAG, "failed to initialize GGML jni"); + return; + } + + try { + initKANTVMgr(); + } catch (Exception e) { + CDELog.j(TAG, "failed to initialize asr subsystem"); + return; + } + + CDELog.j(TAG, "load ggml's LLM model"); + String systemInfo = whispercpp.llm_get_systeminfo(); String phoneInfo = "Device info:" + "\n" + "Brand:" + Build.BRAND + "\n" + "Hardware:" + Build.HARDWARE + "\n" + "OS:" + "Android " + android.os.Build.VERSION.RELEASE + "\n" - + "Arch:" + Build.CPU_ABI ; + + "Arch:" + Build.CPU_ABI + "(" + systemInfo + ")"; _txtGGMLInfo.setText(""); _txtGGMLInfo.append(phoneInfo + "\n"); _txtGGMLInfo.append("Powered by llama.cpp(https://github.com/ggerganov/llama.cpp)\n"); + _btnInference.setOnClickListener(v -> { + String strPrompt = _txtUserInput.getText().toString(); + if (strPrompt.isEmpty()) { + //CDEUtils.showMsgBox(mActivity, "pls check your input"); + //return; + //just for test + strPrompt = strUserInput; + } + strPrompt = strPrompt.trim(); + strUserInput = strPrompt; + CDELog.j(TAG, "User input: \n " + strUserInput); + + CDELog.j(TAG, "strModeName:" + ggmlModelFileName); + + String selectModeFileName = ggmlModelFileName; + String selectModelFilePath = CDEUtils.getDataPath() + selectModeFileName; + CDELog.j(TAG, "selectModelFilePath:" + selectModelFilePath); + File selectModeFile = new File(selectModelFilePath); + displayFileStatus(selectModelFilePath); + if (!selectModeFile.exists()) { + CDELog.j(TAG, "model file not exist:" + selectModeFile.getAbsolutePath()); + } + + if (!selectModeFile.exists()) { + CDEUtils.showMsgBox(mActivity, "pls check whether GGML's model file exist in /sdcard/kantv/"); + return; + } + ggmlModelFileName = selectModeFileName; + CDELog.j(TAG, "model file:" + CDEUtils.getDataPath() + selectModeFileName); + + isBenchmarking.set(true); + + Toast.makeText(mContext, mContext.getString(R.string.ggml_benchmark_start), Toast.LENGTH_LONG).show(); + + _txtLLMInfo.setText(""); + _btnInference.setEnabled(false); + + WindowManager.LayoutParams attributes = mActivity.getWindow().getAttributes(); + attributes.screenBrightness = 1.0f; + mActivity.getWindow().setAttributes(attributes); + mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + + launchGGMLBenchmarkThread(); + + }); endTime = System.currentTimeMillis(); CDELog.j(TAG, "initView cost: " + (endTime - beginTime) + " milliseconds"); } + private final void launchGGMLBenchmarkThread() { + Thread workThread = new Thread(new Runnable() { + @RequiresApi(api = Build.VERSION_CODES.O) + @Override + public void run() { + strBenchmarkInfo = ""; + + while (isBenchmarking.get()) { + beginTime = System.currentTimeMillis(); + _txtGGMLStatus.setText("LLAMA inference is progressing..."); + strBenchmarkInfo = whispercpp.llm_bench( + CDEUtils.getDataPath() + ggmlModelFileName, + strUserInput, + benchmarkIndex, + nThreadCounts); + endTime = System.currentTimeMillis(); + duration = (endTime - beginTime); + isBenchmarking.set(false); + + mActivity.runOnUiThread(new Runnable() { + @Override + public void run() { + String benchmarkTip = "LLAMA inference " + "(model: " + ggmlModelFileName + + " ,threads: " + nThreadCounts + + " ) cost " + duration + " milliseconds"; + benchmarkTip += "\n"; + + if (!strBenchmarkInfo.startsWith("unknown")) { + benchmarkTip += strBenchmarkInfo; + } + + CDELog.j(TAG, benchmarkTip); + _txtGGMLStatus.append(benchmarkTip); + + _btnInference.setEnabled(true); + } + }); + } + + + } + }); + workThread.start(); + + } + @Override public void initListener() { @@ -178,7 +306,6 @@ public void onStop() { } - private void displayFileStatus(String modelFilePath) { _txtGGMLStatus.setText(""); File modelFile = new File(modelFilePath); @@ -189,4 +316,85 @@ private void displayFileStatus(String modelFilePath) { _txtGGMLStatus.append("model file not exist: " + modelFile.getAbsolutePath()); } } + + protected class MyEventListener implements KANTVEventListener { + + MyEventListener() { + } + + + @Override + public void onEvent(KANTVEventType eventType, int what, int arg1, int arg2, Object obj) { + String eventString = "got event from native layer: " + eventType.toString() + " (" + what + ":" + arg1 + " ) :" + (String) obj; + String content = (String) obj; + + if (eventType.getValue() == KANTVEvent.KANTV_ERROR) { + CDELog.j(TAG, "ERROR:" + eventString); + _txtLLMInfo.setText("ERROR:" + content); + } + + if (eventType.getValue() == KANTVEvent.KANTV_INFO) { + if ((arg1 == KANTV_INFO_ASR_STOP) + || (arg1 == KANTV_INFO_ASR_FINALIZE) + ) { + return; + } + + //CDELog.j(TAG, "content:" + content); + if (content.startsWith("unknown")) { + + } else { + if (content.startsWith("llama-timings")) { + _txtGGMLStatus.setText(""); + _txtGGMLStatus.append(content); + } else { + _txtLLMInfo.append(content); + } + } + } + } + } + + + private void initKANTVMgr() { + if (mKANTVMgr != null) { + return; + } + + try { + mKANTVMgr = new KANTVMgr(mEventListener); + if (mKANTVMgr != null) { + mKANTVMgr.initASR(); + mKANTVMgr.startASR(); + } + CDELog.j(TAG, "KANTVMgr version:" + mKANTVMgr.getMgrVersion()); + } catch (KANTVException ex) { + String errorMsg = "An exception was thrown because:\n" + " " + ex.getMessage(); + CDELog.j(TAG, "error occurred: " + errorMsg); + CDEUtils.showMsgBox(mActivity, errorMsg); + ex.printStackTrace(); + } + } + + + public void release() { + if (mKANTVMgr == null) { + return; + } + + try { + CDELog.j(TAG, "release"); + { + mKANTVMgr.finalizeASR(); + mKANTVMgr.stopASR(); + mKANTVMgr.release(); + mKANTVMgr = null; + } + } catch (Exception ex) { + String errorMsg = "An exception was thrown because:\n" + " " + ex.getMessage(); + CDELog.j(TAG, "error occurred: " + errorMsg); + ex.printStackTrace(); + } + } + } diff --git a/cdeosplayer/kantv/src/main/res/drawable/llamacpp_logo.png b/cdeosplayer/kantv/src/main/res/drawable/llamacpp_logo.png index 1b6946be913a95a5d989159b29f58f9ad79744d5..62eb4bead4e9cbf0ab99dd6967a4af45329361f4 100644 GIT binary patch literal 18044 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 C{N?-r literal 31778 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 diff --git a/cdeosplayer/kantv/src/main/res/drawable/textview_border.xml b/cdeosplayer/kantv/src/main/res/drawable/textview_border.xml new file mode 100644 index 000000000..9ba457ede --- /dev/null +++ b/cdeosplayer/kantv/src/main/res/drawable/textview_border.xml @@ -0,0 +1,17 @@ + + + + + + + + + \ No newline at end of file diff --git a/cdeosplayer/kantv/src/main/res/layout/fragment_asr.xml b/cdeosplayer/kantv/src/main/res/layout/fragment_asr.xml index d27501a50..64dfd75ac 100755 --- a/cdeosplayer/kantv/src/main/res/layout/fragment_asr.xml +++ b/cdeosplayer/kantv/src/main/res/layout/fragment_asr.xml @@ -31,7 +31,7 @@ + android:layout_height="210dp" /> + android:layout_height="210dp" /> - - + + +