Spaces:
Build error
Build error
Illumotion
commited on
Commit
•
1ec6819
1
Parent(s):
3d3c4d2
Upload folder using huggingface_hub
Browse files- .flake8 +2 -0
- .gitignore +4 -0
- .pre-commit-config.yaml +15 -0
- Dockerfile +4 -5
- Package.swift +1 -0
- convert.py +18 -8
- examples/baby-llama/baby-llama.cpp +5 -1
- examples/benchmark/benchmark-matmult.cpp +7 -3
- examples/chat-vicuna.sh +41 -0
- examples/common.cpp +21 -1
- examples/common.h +9 -8
- examples/embedding/embedding.cpp +4 -0
- examples/jeopardy/graph.py +4 -3
- examples/main/README.md +1 -0
- examples/main/main.cpp +7 -1
- examples/perplexity/perplexity.cpp +4 -0
- examples/quantize-stats/quantize-stats.cpp +4 -0
- examples/save-load-state/save-load-state.cpp +1 -1
- examples/server/CMakeLists.txt +4 -0
- examples/server/README.md +91 -222
- examples/server/chat.mjs +89 -0
- examples/server/chat.sh +77 -0
- examples/server/server.cpp +856 -718
- examples/simple/CMakeLists.txt +7 -0
- examples/simple/simple.cpp +177 -0
- examples/train-text-from-scratch/README.md +1 -1
- examples/train-text-from-scratch/train-text-from-scratch.cpp +10 -8
- ggml-cuda.cu +1028 -290
- ggml-cuda.h +2 -0
- ggml-metal.h +1 -0
- ggml-metal.m +612 -516
- ggml-metal.metal +149 -0
- ggml.c +12 -0
- ggml.h +1 -0
- gpttype_adapter.cpp +12 -1
- klite.embd +0 -0
- koboldcpp.py +2 -1
- llama.cpp +130 -33
- llama.h +4 -3
- spm-headers/ggml.h +1319 -0
.flake8
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
[flake8]
|
2 |
+
max-line-length = 125
|
.gitignore
CHANGED
@@ -22,6 +22,7 @@ build-metal/
|
|
22 |
build-no-accel/
|
23 |
build-sanitize-addr/
|
24 |
build-sanitize-thread/
|
|
|
25 |
|
26 |
/main
|
27 |
/quantize
|
@@ -29,13 +30,16 @@ build-sanitize-thread/
|
|
29 |
/result
|
30 |
/perplexity
|
31 |
/embedding
|
|
|
32 |
/benchmark-matmult
|
33 |
/vdot
|
|
|
34 |
/Pipfile
|
35 |
/libllama.so
|
36 |
|
37 |
arm_neon.h
|
38 |
compile_commands.json
|
|
|
39 |
|
40 |
__pycache__
|
41 |
|
|
|
22 |
build-no-accel/
|
23 |
build-sanitize-addr/
|
24 |
build-sanitize-thread/
|
25 |
+
out/
|
26 |
|
27 |
/main
|
28 |
/quantize
|
|
|
30 |
/result
|
31 |
/perplexity
|
32 |
/embedding
|
33 |
+
/train-text-from-scratch
|
34 |
/benchmark-matmult
|
35 |
/vdot
|
36 |
+
/server
|
37 |
/Pipfile
|
38 |
/libllama.so
|
39 |
|
40 |
arm_neon.h
|
41 |
compile_commands.json
|
42 |
+
CMakeSettings.json
|
43 |
|
44 |
__pycache__
|
45 |
|
.pre-commit-config.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# See https://pre-commit.com for more information
|
2 |
+
# See https://pre-commit.com/hooks.html for more hooks
|
3 |
+
exclude: prompts/.*.txt
|
4 |
+
repos:
|
5 |
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
6 |
+
rev: v3.2.0
|
7 |
+
hooks:
|
8 |
+
- id: trailing-whitespace
|
9 |
+
- id: end-of-file-fixer
|
10 |
+
- id: check-yaml
|
11 |
+
- id: check-added-large-files
|
12 |
+
- repo: https://github.com/PyCQA/flake8
|
13 |
+
rev: 6.0.0
|
14 |
+
hooks:
|
15 |
+
- id: flake8
|
Dockerfile
CHANGED
@@ -2,10 +2,9 @@ FROM python
|
|
2 |
WORKDIR /app
|
3 |
COPY . .
|
4 |
RUN apt update \
|
5 |
-
&& apt install build-essential wget libopenblas-dev
|
6 |
-
&& make
|
7 |
&& wget https://huggingface.co/xzuyn/GPT-J-Shinen-6B-GGML/resolve/main/ggjtv1-model-q5_1.bin \
|
8 |
-
&& apt remove build-essential wget make -y
|
9 |
-
&& apt autoremove -y
|
10 |
|
11 |
-
ENTRYPOINT ["python", "koboldcpp.py", "ggjtv1-model-q5_1.bin", "--port", "7860", "--smartcontext", "--useclblast"]
|
|
|
2 |
WORKDIR /app
|
3 |
COPY . .
|
4 |
RUN apt update \
|
5 |
+
&& apt install build-essential wget libopenblas-dev make -y \
|
6 |
+
&& make \
|
7 |
&& wget https://huggingface.co/xzuyn/GPT-J-Shinen-6B-GGML/resolve/main/ggjtv1-model-q5_1.bin \
|
8 |
+
&& apt remove build-essential wget make -y
|
|
|
9 |
|
10 |
+
ENTRYPOINT ["python", "koboldcpp.py", "ggjtv1-model-q5_1.bin", "--port", "7860", "--smartcontext", "--useclblast", "{0, 1, 2, 3}"]
|
Package.swift
CHANGED
@@ -11,6 +11,7 @@ let package = Package(
|
|
11 |
.target(
|
12 |
name: "llama",
|
13 |
path: ".",
|
|
|
14 |
sources: ["ggml.c", "llama.cpp"],
|
15 |
publicHeadersPath: "spm-headers",
|
16 |
cSettings: [.unsafeFlags(["-Wno-shorten-64-to-32"]), .define("GGML_USE_ACCELERATE")],
|
|
|
11 |
.target(
|
12 |
name: "llama",
|
13 |
path: ".",
|
14 |
+
exclude: ["ggml-metal.metal"],
|
15 |
sources: ["ggml.c", "llama.cpp"],
|
16 |
publicHeadersPath: "spm-headers",
|
17 |
cSettings: [.unsafeFlags(["-Wno-shorten-64-to-32"]), .define("GGML_USE_ACCELERATE")],
|
convert.py
CHANGED
@@ -512,7 +512,11 @@ class LazyTensor:
|
|
512 |
if not isinstance(self.data_type, QuantizedDataType):
|
513 |
raise Exception(f"Can't turn an unquantized tensor into a quantized type ({data_type})")
|
514 |
if self.data_type.have_g_idx:
|
515 |
-
sys.stderr.write(
|
|
|
|
|
|
|
|
|
516 |
sys.exit(1)
|
517 |
assert not data_type.have_g_idx and self.data_type.have_addends and data_type.have_addends
|
518 |
|
@@ -694,8 +698,9 @@ class LazyUnpickler(pickle.Unpickler):
|
|
694 |
description = f'storage data_type={data_type} path-in-zip={filename} path={self.zip_file.filename}'
|
695 |
return LazyStorage(load=load, kind=pid[1], description=description)
|
696 |
|
697 |
-
|
698 |
-
def lazy_rebuild_tensor_v2(storage: Any, storage_offset: Any, size: Any, stride: Any,
|
|
|
699 |
requires_grad: Any, backward_hooks: Any, metadata: Any = None) -> LazyTensor:
|
700 |
assert isinstance(storage, LazyStorage)
|
701 |
|
@@ -812,7 +817,7 @@ def lazy_load_ggml_file(fp: io.BufferedReader, path: Path) -> ModelPlus:
|
|
812 |
# Use mmap for the actual data to avoid race conditions with the file offset.
|
813 |
off = fp.raw.tell()
|
814 |
mapped = memoryview(mmap.mmap(fp.fileno(), 0, access=mmap.ACCESS_READ))
|
815 |
-
fp.raw.seek(off)
|
816 |
|
817 |
def read_tensor() -> None: # this is a function so that variables captured in `load` don't change
|
818 |
shape_len, name_len, ftype = struct.unpack("iii", must_read(fp, 12))
|
@@ -1054,7 +1059,7 @@ def load_some_model(path: Path) -> ModelPlus:
|
|
1054 |
files = list(path.glob("model-00001-of-*.safetensors"))
|
1055 |
if not files:
|
1056 |
# Try the PyTorch patterns too, with lower priority
|
1057 |
-
globs = ["consolidated.00.pth", "pytorch_model-00001-of-*.bin", "*.pt", "pytorch_model.bin"
|
1058 |
files = [file for glob in globs for file in path.glob(glob)]
|
1059 |
if not files:
|
1060 |
# Try GGML too, but with lower priority, since if both a non-GGML
|
@@ -1094,7 +1099,9 @@ def load_vocab(path: Path) -> SentencePieceVocab:
|
|
1094 |
elif path3.exists():
|
1095 |
path = path3
|
1096 |
else:
|
1097 |
-
raise FileNotFoundError(
|
|
|
|
|
1098 |
added_tokens_path = path.parent / "added_tokens.json"
|
1099 |
print(f"Loading vocab file {path}")
|
1100 |
return SentencePieceVocab(path, added_tokens_path if added_tokens_path.exists() else None)
|
@@ -1110,7 +1117,9 @@ def default_outfile(model_paths: List[Path], params: Params) -> Path:
|
|
1110 |
}[params.file_type]
|
1111 |
ret = model_paths[0].parent / f"ggml-model-{namestr}.bin"
|
1112 |
if ret in model_paths:
|
1113 |
-
sys.stderr.write(
|
|
|
|
|
1114 |
sys.exit(1)
|
1115 |
return ret
|
1116 |
|
@@ -1131,7 +1140,8 @@ def main(args_in: Optional[List[str]] = None) -> None:
|
|
1131 |
parser.add_argument("--outtype", choices=["f32", "f16", "q4_1", "q4_0"], help="output format (default: based on input)")
|
1132 |
parser.add_argument("--vocab-dir", type=Path, help="directory containing tokenizer.model, if separate from model file")
|
1133 |
parser.add_argument("--outfile", type=Path, help="path to write to; default: based on input")
|
1134 |
-
parser.add_argument("model", type=Path,
|
|
|
1135 |
args = parser.parse_args(args_in)
|
1136 |
|
1137 |
vocab: Vocab
|
|
|
512 |
if not isinstance(self.data_type, QuantizedDataType):
|
513 |
raise Exception(f"Can't turn an unquantized tensor into a quantized type ({data_type})")
|
514 |
if self.data_type.have_g_idx:
|
515 |
+
sys.stderr.write(
|
516 |
+
"Error: Input uses the newer GPTQ-for-LLaMa format (using g_idx), "
|
517 |
+
"which is not yet natively supported by GGML. "
|
518 |
+
"For now you can still convert this model by passing `--outtype f16` to dequantize, "
|
519 |
+
"but that will result in a much larger output file for no quality benefit.\n")
|
520 |
sys.exit(1)
|
521 |
assert not data_type.have_g_idx and self.data_type.have_addends and data_type.have_addends
|
522 |
|
|
|
698 |
description = f'storage data_type={data_type} path-in-zip={filename} path={self.zip_file.filename}'
|
699 |
return LazyStorage(load=load, kind=pid[1], description=description)
|
700 |
|
701 |
+
# @staticmethod
|
702 |
+
def lazy_rebuild_tensor_v2(storage: Any, storage_offset: Any, size: Any, stride: Any,
|
703 |
+
# pyright: ignore[reportSelfClsParameterName]
|
704 |
requires_grad: Any, backward_hooks: Any, metadata: Any = None) -> LazyTensor:
|
705 |
assert isinstance(storage, LazyStorage)
|
706 |
|
|
|
817 |
# Use mmap for the actual data to avoid race conditions with the file offset.
|
818 |
off = fp.raw.tell()
|
819 |
mapped = memoryview(mmap.mmap(fp.fileno(), 0, access=mmap.ACCESS_READ))
|
820 |
+
fp.raw.seek(off) # needed on Windows
|
821 |
|
822 |
def read_tensor() -> None: # this is a function so that variables captured in `load` don't change
|
823 |
shape_len, name_len, ftype = struct.unpack("iii", must_read(fp, 12))
|
|
|
1059 |
files = list(path.glob("model-00001-of-*.safetensors"))
|
1060 |
if not files:
|
1061 |
# Try the PyTorch patterns too, with lower priority
|
1062 |
+
globs = ["consolidated.00.pth", "pytorch_model-00001-of-*.bin", "*.pt", "pytorch_model.bin"]
|
1063 |
files = [file for glob in globs for file in path.glob(glob)]
|
1064 |
if not files:
|
1065 |
# Try GGML too, but with lower priority, since if both a non-GGML
|
|
|
1099 |
elif path3.exists():
|
1100 |
path = path3
|
1101 |
else:
|
1102 |
+
raise FileNotFoundError(
|
1103 |
+
f"Could not find tokenizer.model in {path} or its parent; "
|
1104 |
+
"if it's in another directory, pass the directory as --vocab-dir")
|
1105 |
added_tokens_path = path.parent / "added_tokens.json"
|
1106 |
print(f"Loading vocab file {path}")
|
1107 |
return SentencePieceVocab(path, added_tokens_path if added_tokens_path.exists() else None)
|
|
|
1117 |
}[params.file_type]
|
1118 |
ret = model_paths[0].parent / f"ggml-model-{namestr}.bin"
|
1119 |
if ret in model_paths:
|
1120 |
+
sys.stderr.write(
|
1121 |
+
f"Error: Default output path ({ret}) would overwrite the input. "
|
1122 |
+
"Please explicitly specify a path using --outfile.\n")
|
1123 |
sys.exit(1)
|
1124 |
return ret
|
1125 |
|
|
|
1140 |
parser.add_argument("--outtype", choices=["f32", "f16", "q4_1", "q4_0"], help="output format (default: based on input)")
|
1141 |
parser.add_argument("--vocab-dir", type=Path, help="directory containing tokenizer.model, if separate from model file")
|
1142 |
parser.add_argument("--outfile", type=Path, help="path to write to; default: based on input")
|
1143 |
+
parser.add_argument("model", type=Path,
|
1144 |
+
help="directory containing model file, or model file itself (*.pth, *.pt, *.bin)")
|
1145 |
args = parser.parse_args(args_in)
|
1146 |
|
1147 |
vocab: Vocab
|
examples/baby-llama/baby-llama.cpp
CHANGED
@@ -4,6 +4,10 @@
|
|
4 |
#include <random>
|
5 |
#include <cstring>
|
6 |
|
|
|
|
|
|
|
|
|
7 |
float frand() {
|
8 |
return (float)rand()/(float)RAND_MAX;
|
9 |
}
|
@@ -1470,7 +1474,7 @@ struct ggml_tensor * square_error_loss(struct ggml_context * ctx, struct ggml_te
|
|
1470 |
}
|
1471 |
|
1472 |
struct ggml_tensor * cross_entropy_loss(struct ggml_context * ctx, struct ggml_tensor * a, struct ggml_tensor * b) {
|
1473 |
-
const float eps = 1e-
|
1474 |
return
|
1475 |
ggml_sum(ctx,
|
1476 |
ggml_neg(ctx,
|
|
|
4 |
#include <random>
|
5 |
#include <cstring>
|
6 |
|
7 |
+
#if defined(_MSC_VER)
|
8 |
+
#pragma warning(disable: 4244 4267) // possible loss of data
|
9 |
+
#endif
|
10 |
+
|
11 |
float frand() {
|
12 |
return (float)rand()/(float)RAND_MAX;
|
13 |
}
|
|
|
1474 |
}
|
1475 |
|
1476 |
struct ggml_tensor * cross_entropy_loss(struct ggml_context * ctx, struct ggml_tensor * a, struct ggml_tensor * b) {
|
1477 |
+
const float eps = 1e-3f;
|
1478 |
return
|
1479 |
ggml_sum(ctx,
|
1480 |
ggml_neg(ctx,
|
examples/benchmark/benchmark-matmult.cpp
CHANGED
@@ -16,6 +16,10 @@
|
|
16 |
#include <iterator>
|
17 |
#include <algorithm>
|
18 |
|
|
|
|
|
|
|
|
|
19 |
float tensor_sum_elements(const ggml_tensor * tensor) {
|
20 |
float sum = 0;
|
21 |
if (tensor->type==GGML_TYPE_F32) {
|
@@ -29,9 +33,9 @@ float tensor_sum_elements(const ggml_tensor * tensor) {
|
|
29 |
}
|
30 |
|
31 |
void tensor_dump(const ggml_tensor * tensor, const char * name) {
|
32 |
-
printf("%15s: type = %i (%5s) ne = %
|
33 |
tensor->type, ggml_type_name(tensor->type),
|
34 |
-
|
35 |
float sum = tensor_sum_elements(tensor);
|
36 |
printf("Sum of tensor %s is %6.2f\n", name, sum);
|
37 |
}
|
@@ -120,7 +124,7 @@ int main(int argc, char ** argv) {
|
|
120 |
ctx_size += sizex*sizey*ggml_type_sizef(GGML_TYPE_F32); // BLAS
|
121 |
ctx_size += 1024*1024*16;
|
122 |
|
123 |
-
printf("Allocating Memory of size %
|
124 |
|
125 |
struct ggml_init_params params = {
|
126 |
/*.mem_size =*/ ctx_size,
|
|
|
16 |
#include <iterator>
|
17 |
#include <algorithm>
|
18 |
|
19 |
+
#if defined(_MSC_VER)
|
20 |
+
#pragma warning(disable: 4244 4267) // possible loss of data
|
21 |
+
#endif
|
22 |
+
|
23 |
float tensor_sum_elements(const ggml_tensor * tensor) {
|
24 |
float sum = 0;
|
25 |
if (tensor->type==GGML_TYPE_F32) {
|
|
|
33 |
}
|
34 |
|
35 |
void tensor_dump(const ggml_tensor * tensor, const char * name) {
|
36 |
+
printf("%15s: type = %i (%5s) ne = %5" PRIi64 " x %5" PRIi64 " x %5" PRIi64 ", nb = (%5zi, %5zi, %5zi) - ", name,
|
37 |
tensor->type, ggml_type_name(tensor->type),
|
38 |
+
tensor->ne[0], tensor->ne[1], tensor->ne[2], tensor->nb[0], tensor->nb[1], tensor->nb[2]);
|
39 |
float sum = tensor_sum_elements(tensor);
|
40 |
printf("Sum of tensor %s is %6.2f\n", name, sum);
|
41 |
}
|
|
|
124 |
ctx_size += sizex*sizey*ggml_type_sizef(GGML_TYPE_F32); // BLAS
|
125 |
ctx_size += 1024*1024*16;
|
126 |
|
127 |
+
printf("Allocating Memory of size %zi bytes, %zi MB\n",ctx_size, (ctx_size/1024/1024));
|
128 |
|
129 |
struct ggml_init_params params = {
|
130 |
/*.mem_size =*/ ctx_size,
|
examples/chat-vicuna.sh
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/bin/bash
|
2 |
+
|
3 |
+
set -e
|
4 |
+
|
5 |
+
cd "$(dirname "$0")/.." || exit
|
6 |
+
|
7 |
+
MODEL="${MODEL:-./models/ggml-vic13b-uncensored-q5_0.bin}"
|
8 |
+
PROMPT_TEMPLATE=${PROMPT_TEMPLATE:-./prompts/chat.txt}
|
9 |
+
USER_NAME="### Human"
|
10 |
+
AI_NAME="### Assistant"
|
11 |
+
|
12 |
+
# Adjust to the number of CPU cores you want to use.
|
13 |
+
N_THREAD="${N_THREAD:-8}"
|
14 |
+
# Number of tokens to predict (made it larger than default because we want a long interaction)
|
15 |
+
N_PREDICTS="${N_PREDICTS:-2048}"
|
16 |
+
|
17 |
+
# Note: you can also override the generation options by specifying them on the command line:
|
18 |
+
# For example, override the context size by doing: ./chatLLaMa --ctx_size 1024
|
19 |
+
GEN_OPTIONS="${GEN_OPTIONS:---ctx_size 2048 --temp 0.7 --top_k 40 --top_p 0.5 --repeat_last_n 256 --batch_size 1024 --repeat_penalty 1.17647}"
|
20 |
+
|
21 |
+
DATE_TIME=$(date +%H:%M)
|
22 |
+
DATE_YEAR=$(date +%Y)
|
23 |
+
|
24 |
+
PROMPT_FILE=$(mktemp -t llamacpp_prompt.XXXXXXX.txt)
|
25 |
+
|
26 |
+
sed -e "s/\[\[USER_NAME\]\]/$USER_NAME/g" \
|
27 |
+
-e "s/\[\[AI_NAME\]\]/$AI_NAME/g" \
|
28 |
+
-e "s/\[\[DATE_TIME\]\]/$DATE_TIME/g" \
|
29 |
+
-e "s/\[\[DATE_YEAR\]\]/$DATE_YEAR/g" \
|
30 |
+
$PROMPT_TEMPLATE > $PROMPT_FILE
|
31 |
+
|
32 |
+
# shellcheck disable=SC2086 # Intended splitting of GEN_OPTIONS
|
33 |
+
./bin/main $GEN_OPTIONS \
|
34 |
+
--model "$MODEL" \
|
35 |
+
--threads "$N_THREAD" \
|
36 |
+
--n_predict "$N_PREDICTS" \
|
37 |
+
--color --interactive \
|
38 |
+
--file ${PROMPT_FILE} \
|
39 |
+
--reverse-prompt "### Human:" \
|
40 |
+
--in-prefix ' ' \
|
41 |
+
"$@"
|
examples/common.cpp
CHANGED
@@ -28,6 +28,10 @@
|
|
28 |
#include <wchar.h>
|
29 |
#endif
|
30 |
|
|
|
|
|
|
|
|
|
31 |
int32_t get_num_physical_cores() {
|
32 |
#ifdef __linux__
|
33 |
// enumerate the set of thread siblings, num entries is num cores
|
@@ -331,6 +335,12 @@ bool gpt_params_parse(int argc, char ** argv, gpt_params & params) {
|
|
331 |
}
|
332 |
#else
|
333 |
fprintf(stderr, "warning: llama.cpp was compiled without cuBLAS. It is not possible to set a tensor split.\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
334 |
#endif // GGML_USE_CUBLAS
|
335 |
} else if (arg == "--no-mmap") {
|
336 |
params.use_mmap = false;
|
@@ -367,7 +377,7 @@ bool gpt_params_parse(int argc, char ** argv, gpt_params & params) {
|
|
367 |
} else {
|
368 |
throw std::exception();
|
369 |
}
|
370 |
-
} catch (const std::exception
|
371 |
invalid_param = true;
|
372 |
break;
|
373 |
}
|
@@ -406,6 +416,14 @@ bool gpt_params_parse(int argc, char ** argv, gpt_params & params) {
|
|
406 |
gpt_print_usage(argc, argv, default_params);
|
407 |
exit(1);
|
408 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
409 |
if (escape_prompt) {
|
410 |
process_escapes(params.prompt);
|
411 |
}
|
@@ -479,6 +497,7 @@ void gpt_print_usage(int /*argc*/, char ** argv, const gpt_params & params) {
|
|
479 |
fprintf(stderr, " -ts SPLIT --tensor-split SPLIT\n");
|
480 |
fprintf(stderr, " how to split tensors across multiple GPUs, comma-separated list of proportions, e.g. 3,1\n");
|
481 |
fprintf(stderr, " -mg i, --main-gpu i the GPU to use for scratch and small tensors\n" );
|
|
|
482 |
#endif
|
483 |
fprintf(stderr, " --mtest compute maximum memory usage\n");
|
484 |
fprintf(stderr, " --export export the computation graph to 'llama.ggml'\n");
|
@@ -528,6 +547,7 @@ struct llama_context * llama_init_from_gpt_params(const gpt_params & params) {
|
|
528 |
lparams.n_gpu_layers = params.n_gpu_layers;
|
529 |
lparams.main_gpu = params.main_gpu;
|
530 |
memcpy(lparams.tensor_split, params.tensor_split, LLAMA_MAX_DEVICES*sizeof(float));
|
|
|
531 |
lparams.seed = params.seed;
|
532 |
lparams.f16_kv = params.memory_f16;
|
533 |
lparams.use_mmap = params.use_mmap;
|
|
|
28 |
#include <wchar.h>
|
29 |
#endif
|
30 |
|
31 |
+
#if defined(_MSC_VER)
|
32 |
+
#pragma warning(disable: 4244 4267) // possible loss of data
|
33 |
+
#endif
|
34 |
+
|
35 |
int32_t get_num_physical_cores() {
|
36 |
#ifdef __linux__
|
37 |
// enumerate the set of thread siblings, num entries is num cores
|
|
|
335 |
}
|
336 |
#else
|
337 |
fprintf(stderr, "warning: llama.cpp was compiled without cuBLAS. It is not possible to set a tensor split.\n");
|
338 |
+
#endif // GGML_USE_CUBLAS
|
339 |
+
} else if (arg == "--low-vram" || arg == "-lv") {
|
340 |
+
#ifdef GGML_USE_CUBLAS
|
341 |
+
params.low_vram = true;
|
342 |
+
#else
|
343 |
+
fprintf(stderr, "warning: llama.cpp was compiled without cuBLAS. It is not possible to set lower vram usage.\n");
|
344 |
#endif // GGML_USE_CUBLAS
|
345 |
} else if (arg == "--no-mmap") {
|
346 |
params.use_mmap = false;
|
|
|
377 |
} else {
|
378 |
throw std::exception();
|
379 |
}
|
380 |
+
} catch (const std::exception&) {
|
381 |
invalid_param = true;
|
382 |
break;
|
383 |
}
|
|
|
416 |
gpt_print_usage(argc, argv, default_params);
|
417 |
exit(1);
|
418 |
}
|
419 |
+
|
420 |
+
#ifdef GGML_USE_CUBLAS
|
421 |
+
if (!params.lora_adapter.empty() && params.n_gpu_layers > 0) {
|
422 |
+
fprintf(stderr, "%s: error: the simultaneous use of LoRAs and GPU acceleration is not supported", __func__);
|
423 |
+
exit(1);
|
424 |
+
}
|
425 |
+
#endif // GGML_USE_CUBLAS
|
426 |
+
|
427 |
if (escape_prompt) {
|
428 |
process_escapes(params.prompt);
|
429 |
}
|
|
|
497 |
fprintf(stderr, " -ts SPLIT --tensor-split SPLIT\n");
|
498 |
fprintf(stderr, " how to split tensors across multiple GPUs, comma-separated list of proportions, e.g. 3,1\n");
|
499 |
fprintf(stderr, " -mg i, --main-gpu i the GPU to use for scratch and small tensors\n" );
|
500 |
+
fprintf(stderr, " -lv, --low-vram don't allocate VRAM scratch buffer\n" );
|
501 |
#endif
|
502 |
fprintf(stderr, " --mtest compute maximum memory usage\n");
|
503 |
fprintf(stderr, " --export export the computation graph to 'llama.ggml'\n");
|
|
|
547 |
lparams.n_gpu_layers = params.n_gpu_layers;
|
548 |
lparams.main_gpu = params.main_gpu;
|
549 |
memcpy(lparams.tensor_split, params.tensor_split, LLAMA_MAX_DEVICES*sizeof(float));
|
550 |
+
lparams.low_vram = params.low_vram;
|
551 |
lparams.seed = params.seed;
|
552 |
lparams.f16_kv = params.memory_f16;
|
553 |
lparams.use_mmap = params.use_mmap;
|
examples/common.h
CHANGED
@@ -21,15 +21,16 @@
|
|
21 |
int32_t get_num_physical_cores();
|
22 |
|
23 |
struct gpt_params {
|
24 |
-
int32_t seed
|
25 |
-
int32_t n_threads
|
26 |
-
int32_t n_predict
|
27 |
-
int32_t n_ctx
|
28 |
-
int32_t n_batch
|
29 |
-
int32_t n_keep
|
30 |
-
int32_t n_gpu_layers
|
31 |
-
int32_t main_gpu
|
32 |
float tensor_split[LLAMA_MAX_DEVICES] = {0}; // how split tensors should be distributed across GPUs
|
|
|
33 |
|
34 |
// sampling parameters
|
35 |
std::unordered_map<llama_token, float> logit_bias; // logit bias for specific tokens
|
|
|
21 |
int32_t get_num_physical_cores();
|
22 |
|
23 |
struct gpt_params {
|
24 |
+
int32_t seed = -1; // RNG seed
|
25 |
+
int32_t n_threads = get_num_physical_cores();
|
26 |
+
int32_t n_predict = -1; // new tokens to predict
|
27 |
+
int32_t n_ctx = 512; // context size
|
28 |
+
int32_t n_batch = 512; // batch size for prompt processing (must be >=32 to use BLAS)
|
29 |
+
int32_t n_keep = 0; // number of tokens to keep from initial prompt
|
30 |
+
int32_t n_gpu_layers = 0; // number of layers to store in VRAM
|
31 |
+
int32_t main_gpu = 0; // the GPU that is used for scratch and small tensors
|
32 |
float tensor_split[LLAMA_MAX_DEVICES] = {0}; // how split tensors should be distributed across GPUs
|
33 |
+
bool low_vram = 0; // if true, reduce VRAM usage at the cost of performance
|
34 |
|
35 |
// sampling parameters
|
36 |
std::unordered_map<llama_token, float> logit_bias; // logit bias for specific tokens
|
examples/embedding/embedding.cpp
CHANGED
@@ -4,6 +4,10 @@
|
|
4 |
|
5 |
#include <ctime>
|
6 |
|
|
|
|
|
|
|
|
|
7 |
int main(int argc, char ** argv) {
|
8 |
gpt_params params;
|
9 |
|
|
|
4 |
|
5 |
#include <ctime>
|
6 |
|
7 |
+
#if defined(_MSC_VER)
|
8 |
+
#pragma warning(disable: 4244 4267) // possible loss of data
|
9 |
+
#endif
|
10 |
+
|
11 |
int main(int argc, char ** argv) {
|
12 |
gpt_params params;
|
13 |
|
examples/jeopardy/graph.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
import matplotlib.pyplot as plt
|
2 |
-
import
|
3 |
import csv
|
4 |
|
5 |
labels = []
|
@@ -8,6 +8,7 @@ numEntries = 1
|
|
8 |
|
9 |
rows = []
|
10 |
|
|
|
11 |
def bar_chart(numbers, labels, pos):
|
12 |
plt.bar(pos, numbers, color='blue')
|
13 |
plt.xticks(ticks=pos, labels=labels)
|
@@ -16,6 +17,7 @@ def bar_chart(numbers, labels, pos):
|
|
16 |
plt.ylabel("Questions Correct")
|
17 |
plt.show()
|
18 |
|
|
|
19 |
def calculatecorrect():
|
20 |
directory = os.fsencode("./examples/jeopardy/results/")
|
21 |
csv_reader = csv.reader(open("./examples/jeopardy/qasheet.csv", 'rt'), delimiter=',')
|
@@ -38,14 +40,13 @@ def calculatecorrect():
|
|
38 |
print(line)
|
39 |
else:
|
40 |
print("Correct answer: " + rows[i][2] + "\n")
|
41 |
-
i+=1
|
42 |
print("Did the AI get the question right? (y/n)")
|
43 |
if input() == "y":
|
44 |
totalcorrect += 1
|
45 |
numbers.append(totalcorrect)
|
46 |
|
47 |
|
48 |
-
|
49 |
if __name__ == '__main__':
|
50 |
calculatecorrect()
|
51 |
pos = list(range(numEntries))
|
|
|
1 |
import matplotlib.pyplot as plt
|
2 |
+
import os
|
3 |
import csv
|
4 |
|
5 |
labels = []
|
|
|
8 |
|
9 |
rows = []
|
10 |
|
11 |
+
|
12 |
def bar_chart(numbers, labels, pos):
|
13 |
plt.bar(pos, numbers, color='blue')
|
14 |
plt.xticks(ticks=pos, labels=labels)
|
|
|
17 |
plt.ylabel("Questions Correct")
|
18 |
plt.show()
|
19 |
|
20 |
+
|
21 |
def calculatecorrect():
|
22 |
directory = os.fsencode("./examples/jeopardy/results/")
|
23 |
csv_reader = csv.reader(open("./examples/jeopardy/qasheet.csv", 'rt'), delimiter=',')
|
|
|
40 |
print(line)
|
41 |
else:
|
42 |
print("Correct answer: " + rows[i][2] + "\n")
|
43 |
+
i += 1
|
44 |
print("Did the AI get the question right? (y/n)")
|
45 |
if input() == "y":
|
46 |
totalcorrect += 1
|
47 |
numbers.append(totalcorrect)
|
48 |
|
49 |
|
|
|
50 |
if __name__ == '__main__':
|
51 |
calculatecorrect()
|
52 |
pos = list(range(numEntries))
|
examples/main/README.md
CHANGED
@@ -288,5 +288,6 @@ These options provide extra functionality and customization when running the LLa
|
|
288 |
- `-ngl N, --n-gpu-layers N`: When compiled with appropriate support (currently CLBlast or cuBLAS), this option allows offloading some layers to the GPU for computation. Generally results in increased performance.
|
289 |
- `-mg i, --main-gpu i`: When using multiple GPUs this option controls which GPU is used for small tensors for which the overhead of splitting the computation across all GPUs is not worthwhile. The GPU in question will use slightly more VRAM to store a scratch buffer for temporary results. By default GPU 0 is used. Requires cuBLAS.
|
290 |
- `-ts SPLIT, --tensor-split SPLIT`: When using multiple GPUs this option controls how large tensors should be split across all GPUs. `SPLIT` is a comma-separated list of non-negative values that assigns the proportion of data that each GPU should get in order. For example, "3,2" will assign 60% of the data to GPU 0 and 40% to GPU 1. By default the data is split in proportion to VRAM but this may not be optimal for performance. Requires cuBLAS.
|
|
|
291 |
- `--lora FNAME`: Apply a LoRA (Low-Rank Adaptation) adapter to the model (implies --no-mmap). This allows you to adapt the pretrained model to specific tasks or domains.
|
292 |
- `--lora-base FNAME`: Optional model to use as a base for the layers modified by the LoRA adapter. This flag is used in conjunction with the `--lora` flag, and specifies the base model for the adaptation.
|
|
|
288 |
- `-ngl N, --n-gpu-layers N`: When compiled with appropriate support (currently CLBlast or cuBLAS), this option allows offloading some layers to the GPU for computation. Generally results in increased performance.
|
289 |
- `-mg i, --main-gpu i`: When using multiple GPUs this option controls which GPU is used for small tensors for which the overhead of splitting the computation across all GPUs is not worthwhile. The GPU in question will use slightly more VRAM to store a scratch buffer for temporary results. By default GPU 0 is used. Requires cuBLAS.
|
290 |
- `-ts SPLIT, --tensor-split SPLIT`: When using multiple GPUs this option controls how large tensors should be split across all GPUs. `SPLIT` is a comma-separated list of non-negative values that assigns the proportion of data that each GPU should get in order. For example, "3,2" will assign 60% of the data to GPU 0 and 40% to GPU 1. By default the data is split in proportion to VRAM but this may not be optimal for performance. Requires cuBLAS.
|
291 |
+
- `-lv, --low-vram`: Do not allocate a VRAM scratch buffer for holding temporary results. Reduces VRAM usage at the cost of performance, particularly prompt processing speed. Requires cuBLAS.
|
292 |
- `--lora FNAME`: Apply a LoRA (Low-Rank Adaptation) adapter to the model (implies --no-mmap). This allows you to adapt the pretrained model to specific tasks or domains.
|
293 |
- `--lora-base FNAME`: Optional model to use as a base for the layers modified by the LoRA adapter. This flag is used in conjunction with the `--lora` flag, and specifies the base model for the adaptation.
|
examples/main/main.cpp
CHANGED
@@ -23,11 +23,17 @@
|
|
23 |
#include <unistd.h>
|
24 |
#elif defined (_WIN32)
|
25 |
#define WIN32_LEAN_AND_MEAN
|
|
|
26 |
#define NOMINMAX
|
|
|
27 |
#include <windows.h>
|
28 |
#include <signal.h>
|
29 |
#endif
|
30 |
|
|
|
|
|
|
|
|
|
31 |
static console_state con_st;
|
32 |
static llama_context ** g_ctx;
|
33 |
|
@@ -348,7 +354,7 @@ int main(int argc, char ** argv) {
|
|
348 |
if ((int)embd.size() > max_embd_size) {
|
349 |
auto skipped_tokens = embd.size() - max_embd_size;
|
350 |
console_set_color(con_st, CONSOLE_COLOR_ERROR);
|
351 |
-
printf("<<input too long: skipped %
|
352 |
console_set_color(con_st, CONSOLE_COLOR_DEFAULT);
|
353 |
fflush(stdout);
|
354 |
embd.resize(max_embd_size);
|
|
|
23 |
#include <unistd.h>
|
24 |
#elif defined (_WIN32)
|
25 |
#define WIN32_LEAN_AND_MEAN
|
26 |
+
#ifndef NOMINMAX
|
27 |
#define NOMINMAX
|
28 |
+
#endif
|
29 |
#include <windows.h>
|
30 |
#include <signal.h>
|
31 |
#endif
|
32 |
|
33 |
+
#if defined(_MSC_VER)
|
34 |
+
#pragma warning(disable: 4244 4267) // possible loss of data
|
35 |
+
#endif
|
36 |
+
|
37 |
static console_state con_st;
|
38 |
static llama_context ** g_ctx;
|
39 |
|
|
|
354 |
if ((int)embd.size() > max_embd_size) {
|
355 |
auto skipped_tokens = embd.size() - max_embd_size;
|
356 |
console_set_color(con_st, CONSOLE_COLOR_ERROR);
|
357 |
+
printf("<<input too long: skipped %" PRIu64 " token%s>>", skipped_tokens, skipped_tokens != 1 ? "s" : "");
|
358 |
console_set_color(con_st, CONSOLE_COLOR_DEFAULT);
|
359 |
fflush(stdout);
|
360 |
embd.resize(max_embd_size);
|
examples/perplexity/perplexity.cpp
CHANGED
@@ -5,6 +5,10 @@
|
|
5 |
#include <cmath>
|
6 |
#include <ctime>
|
7 |
|
|
|
|
|
|
|
|
|
8 |
std::vector<float> softmax(const std::vector<float>& logits) {
|
9 |
std::vector<float> probs(logits.size());
|
10 |
float max_logit = logits[0];
|
|
|
5 |
#include <cmath>
|
6 |
#include <ctime>
|
7 |
|
8 |
+
#if defined(_MSC_VER)
|
9 |
+
#pragma warning(disable: 4244 4267) // possible loss of data
|
10 |
+
#endif
|
11 |
+
|
12 |
std::vector<float> softmax(const std::vector<float>& logits) {
|
13 |
std::vector<float> probs(logits.size());
|
14 |
float max_logit = logits[0];
|
examples/quantize-stats/quantize-stats.cpp
CHANGED
@@ -19,6 +19,10 @@
|
|
19 |
#include <thread>
|
20 |
#include <mutex>
|
21 |
|
|
|
|
|
|
|
|
|
22 |
struct quantize_stats_params {
|
23 |
std::string model = "models/7B/ggml-model-f16.bin";
|
24 |
bool verbose = false;
|
|
|
19 |
#include <thread>
|
20 |
#include <mutex>
|
21 |
|
22 |
+
#if defined(_MSC_VER)
|
23 |
+
#pragma warning(disable: 4244 4267) // possible loss of data
|
24 |
+
#endif
|
25 |
+
|
26 |
struct quantize_stats_params {
|
27 |
std::string model = "models/7B/ggml-model-f16.bin";
|
28 |
bool verbose = false;
|
examples/save-load-state/save-load-state.cpp
CHANGED
@@ -37,7 +37,7 @@ int main(int argc, char ** argv) {
|
|
37 |
// init
|
38 |
auto ctx = llama_init_from_file(params.model.c_str(), lparams);
|
39 |
auto tokens = std::vector<llama_token>(params.n_ctx);
|
40 |
-
auto n_prompt_tokens = llama_tokenize(ctx, params.prompt.c_str(), tokens.data(), tokens.size(), true);
|
41 |
|
42 |
if (n_prompt_tokens < 1) {
|
43 |
fprintf(stderr, "%s : failed to tokenize prompt\n", __func__);
|
|
|
37 |
// init
|
38 |
auto ctx = llama_init_from_file(params.model.c_str(), lparams);
|
39 |
auto tokens = std::vector<llama_token>(params.n_ctx);
|
40 |
+
auto n_prompt_tokens = llama_tokenize(ctx, params.prompt.c_str(), tokens.data(), int(tokens.size()), true);
|
41 |
|
42 |
if (n_prompt_tokens < 1) {
|
43 |
fprintf(stderr, "%s : failed to tokenize prompt\n", __func__);
|
examples/server/CMakeLists.txt
CHANGED
@@ -1,6 +1,10 @@
|
|
1 |
set(TARGET server)
|
|
|
2 |
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
3 |
add_executable(${TARGET} server.cpp json.hpp httplib.h)
|
|
|
|
|
|
|
4 |
target_link_libraries(${TARGET} PRIVATE common llama ${CMAKE_THREAD_LIBS_INIT})
|
5 |
target_compile_features(${TARGET} PRIVATE cxx_std_11)
|
6 |
if(TARGET BUILD_INFO)
|
|
|
1 |
set(TARGET server)
|
2 |
+
option(LLAMA_SERVER_VERBOSE "Build verbose logging option for Server" ON)
|
3 |
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
4 |
add_executable(${TARGET} server.cpp json.hpp httplib.h)
|
5 |
+
target_compile_definitions(${TARGET} PRIVATE
|
6 |
+
SERVER_VERBOSE=$<BOOL:${LLAMA_SERVER_VERBOSE}>
|
7 |
+
)
|
8 |
target_link_libraries(${TARGET} PRIVATE common llama ${CMAKE_THREAD_LIBS_INIT})
|
9 |
target_compile_features(${TARGET} PRIVATE cxx_std_11)
|
10 |
if(TARGET BUILD_INFO)
|
examples/server/README.md
CHANGED
@@ -1,33 +1,74 @@
|
|
1 |
# llama.cpp/example/server
|
2 |
|
3 |
-
This example
|
4 |
|
5 |
-
|
6 |
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
## Quick Start
|
15 |
|
16 |
To get started right away, run the following command, making sure to use the correct path for the model you have:
|
17 |
|
18 |
-
|
19 |
|
20 |
```bash
|
21 |
-
./server -m models/7B/ggml-model.bin
|
22 |
```
|
23 |
|
24 |
-
|
25 |
|
26 |
```powershell
|
27 |
-
server.exe -m models\7B\ggml-model.bin
|
28 |
```
|
29 |
|
30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
|
32 |
## Node JS Test
|
33 |
|
@@ -50,7 +91,6 @@ const prompt = `Building a website can be done in 10 simple steps:`;
|
|
50 |
async function Test() {
|
51 |
let result = await axios.post("http://127.0.0.1:8080/completion", {
|
52 |
prompt,
|
53 |
-
batch_size: 128,
|
54 |
n_predict: 512,
|
55 |
});
|
56 |
|
@@ -69,246 +109,75 @@ node .
|
|
69 |
|
70 |
## API Endpoints
|
71 |
|
72 |
-
|
73 |
|
74 |
-
|
75 |
|
76 |
-
|
77 |
|
78 |
-
`
|
79 |
|
80 |
-
`
|
81 |
|
82 |
-
`
|
83 |
|
84 |
-
`
|
|
|
85 |
|
86 |
-
`
|
87 |
|
88 |
-
`
|
89 |
|
90 |
-
`
|
|
|
91 |
|
92 |
-
`
|
93 |
|
94 |
-
`
|
95 |
|
96 |
-
`
|
97 |
|
98 |
-
`
|
99 |
|
100 |
-
`
|
101 |
|
102 |
-
|
103 |
|
104 |
-
|
105 |
|
106 |
-
`
|
107 |
|
108 |
-
`
|
109 |
|
110 |
-
|
111 |
|
112 |
-
|
113 |
|
114 |
-
|
115 |
|
116 |
-
`
|
117 |
|
118 |
-
- **
|
119 |
|
120 |
-
*Options:*
|
121 |
|
122 |
-
`
|
123 |
|
124 |
## More examples
|
125 |
|
126 |
### Interactive mode
|
127 |
|
128 |
-
|
129 |
-
|
130 |
-
The prompt should be generated by you, according to the model's guidelines. You should keep adding the model's completions to the context as well.
|
131 |
-
|
132 |
-
This example works well for `Vicuna - version 1`.
|
133 |
-
|
134 |
-
```javascript
|
135 |
-
const axios = require("axios");
|
136 |
-
|
137 |
-
let prompt = `A chat between a curious human and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the human's questions.
|
138 |
-
### Human: Hello, Assistant.
|
139 |
-
### Assistant: Hello. How may I help you today?
|
140 |
-
### Human: Please tell me the largest city in Europe.
|
141 |
-
### Assistant: Sure. The largest city in Europe is Moscow, the capital of Russia.`;
|
142 |
-
|
143 |
-
async function ChatCompletion(answer) {
|
144 |
-
// the user's next question to the prompt
|
145 |
-
prompt += `\n### Human: ${answer}\n`
|
146 |
-
|
147 |
-
result = await axios.post("http://127.0.0.1:8080/completion", {
|
148 |
-
prompt,
|
149 |
-
batch_size: 128,
|
150 |
-
temperature: 0.2,
|
151 |
-
top_k: 40,
|
152 |
-
top_p: 0.9,
|
153 |
-
n_keep: -1,
|
154 |
-
n_predict: 2048,
|
155 |
-
stop: ["\n### Human:"], // when detect this, stop completion
|
156 |
-
exclude: ["### Assistant:"], // no show in the completion
|
157 |
-
threads: 8,
|
158 |
-
as_loop: true, // use this to request the completion token by token
|
159 |
-
interactive: true, // enable the detection of a stop word
|
160 |
-
});
|
161 |
-
|
162 |
-
// create a loop to receive every token predicted
|
163 |
-
// note: this operation is blocking, avoid use this in a ui thread
|
164 |
-
|
165 |
-
let message = "";
|
166 |
-
while (true) {
|
167 |
-
// you can stop the inference adding '?stop=true' like this http://127.0.0.1:8080/next-token?stop=true
|
168 |
-
result = await axios.get("http://127.0.0.1:8080/next-token");
|
169 |
-
process.stdout.write(result.data.content);
|
170 |
-
message += result.data.content;
|
171 |
-
|
172 |
-
// to avoid an infinite loop
|
173 |
-
if (result.data.stop) {
|
174 |
-
console.log("Completed");
|
175 |
-
// make sure to add the completion to the prompt.
|
176 |
-
prompt += `### Assistant: ${message}`;
|
177 |
-
break;
|
178 |
-
}
|
179 |
-
}
|
180 |
-
}
|
181 |
-
|
182 |
-
// This function should be called every time a question to the model is needed.
|
183 |
-
async function Test() {
|
184 |
-
// the server can't inference in paralell
|
185 |
-
await ChatCompletion("Write a long story about a time magician in a fantasy world");
|
186 |
-
await ChatCompletion("Summary the story");
|
187 |
-
}
|
188 |
-
|
189 |
-
Test();
|
190 |
-
```
|
191 |
-
|
192 |
-
### Alpaca example
|
193 |
-
|
194 |
-
**Temporaly note:** no tested, if you have the model, please test it and report me some issue
|
195 |
-
|
196 |
-
```javascript
|
197 |
-
const axios = require("axios");
|
198 |
-
|
199 |
-
let prompt = `Below is an instruction that describes a task. Write a response that appropriately completes the request.
|
200 |
-
`;
|
201 |
-
|
202 |
-
async function DoInstruction(instruction) {
|
203 |
-
prompt += `\n\n### Instruction:\n\n${instruction}\n\n### Response:\n\n`;
|
204 |
-
result = await axios.post("http://127.0.0.1:8080/completion", {
|
205 |
-
prompt,
|
206 |
-
batch_size: 128,
|
207 |
-
temperature: 0.2,
|
208 |
-
top_k: 40,
|
209 |
-
top_p: 0.9,
|
210 |
-
n_keep: -1,
|
211 |
-
n_predict: 2048,
|
212 |
-
stop: ["### Instruction:\n\n"], // when detect this, stop completion
|
213 |
-
exclude: [], // no show in the completion
|
214 |
-
threads: 8,
|
215 |
-
as_loop: true, // use this to request the completion token by token
|
216 |
-
interactive: true, // enable the detection of a stop word
|
217 |
-
});
|
218 |
-
|
219 |
-
// create a loop to receive every token predicted
|
220 |
-
// note: this operation is blocking, avoid use this in a ui thread
|
221 |
-
|
222 |
-
let message = "";
|
223 |
-
while (true) {
|
224 |
-
result = await axios.get("http://127.0.0.1:8080/next-token");
|
225 |
-
process.stdout.write(result.data.content);
|
226 |
-
message += result.data.content;
|
227 |
-
|
228 |
-
// to avoid an infinite loop
|
229 |
-
if (result.data.stop) {
|
230 |
-
console.log("Completed");
|
231 |
-
// make sure to add the completion and the user's next question to the prompt.
|
232 |
-
prompt += message;
|
233 |
-
break;
|
234 |
-
}
|
235 |
-
}
|
236 |
-
}
|
237 |
-
|
238 |
-
// This function should be called every time a instruction to the model is needed.
|
239 |
-
DoInstruction("Destroy the world"); // as joke
|
240 |
-
```
|
241 |
-
|
242 |
-
### Embeddings
|
243 |
-
|
244 |
-
First, run the server with `--embedding` option:
|
245 |
-
|
246 |
-
```bash
|
247 |
-
server -m models/7B/ggml-model.bin --ctx_size 2048 --embedding
|
248 |
-
```
|
249 |
-
|
250 |
-
Run this code in NodeJS:
|
251 |
|
252 |
-
```
|
253 |
-
|
254 |
-
|
255 |
-
async function Test() {
|
256 |
-
let result = await axios.post("http://127.0.0.1:8080/embedding", {
|
257 |
-
content: `Hello`,
|
258 |
-
threads: 5
|
259 |
-
});
|
260 |
-
// print the embedding array
|
261 |
-
console.log(result.data.embedding);
|
262 |
-
}
|
263 |
-
|
264 |
-
Test();
|
265 |
```
|
266 |
|
267 |
-
|
268 |
-
|
269 |
-
Run
|
270 |
-
|
271 |
-
```javascript
|
272 |
-
const axios = require('axios');
|
273 |
-
|
274 |
-
async function Test() {
|
275 |
-
let result = await axios.post("http://127.0.0.1:8080/tokenize", {
|
276 |
-
content: `Hello`
|
277 |
-
});
|
278 |
-
// print the embedding array
|
279 |
-
console.log(result.data.tokens);
|
280 |
-
}
|
281 |
|
282 |
-
|
|
|
283 |
```
|
284 |
-
|
285 |
-
## Common Options
|
286 |
-
|
287 |
-
- `-m FNAME, --model FNAME`: Specify the path to the LLaMA model file (e.g., `models/7B/ggml-model.bin`).
|
288 |
-
- `-c N, --ctx-size N`: Set the size of the prompt context. The default is 512, but LLaMA models were built with a context of 2048, which will provide better results for longer input/inference.
|
289 |
-
- `-ngl N, --n-gpu-layers N`: When compiled with appropriate support (currently CLBlast or cuBLAS), this option allows offloading some layers to the GPU for computation. Generally results in increased performance.
|
290 |
-
- `-mg i, --main-gpu i`: When using multiple GPUs this option controls which GPU is used for small tensors for which the overhead of splitting the computation across all GPUs is not worthwhile. The GPU in question will use slightly more VRAM to store a scratch buffer for temporary results. By default GPU 0 is used. Requires cuBLAS.
|
291 |
-
- `-ts SPLIT, --tensor-split SPLIT`: When using multiple GPUs this option controls how large tensors should be split across all GPUs. `SPLIT` is a comma-separated list of non-negative values that assigns the proportion of data that each GPU should get in order. For example, "3,2" will assign 60% of the data to GPU 0 and 40% to GPU 1. By default the data is split in proportion to VRAM but this may not be optimal for performance. Requires cuBLAS.
|
292 |
-
- `--embedding`: Enable the embedding mode. **Completion function doesn't work in this mode**.
|
293 |
-
- `--host`: Set the hostname or ip address to listen. Default `127.0.0.1`;
|
294 |
-
- `--port`: Set the port to listen. Default: `8080`.
|
295 |
-
|
296 |
-
### RNG Seed
|
297 |
-
|
298 |
-
- `-s SEED, --seed SEED`: Set the random number generator (RNG) seed (default: -1, < 0 = random seed).
|
299 |
-
|
300 |
-
The RNG seed is used to initialize the random number generator that influences the text generation process. By setting a specific seed value, you can obtain consistent and reproducible results across multiple runs with the same input and settings. This can be helpful for testing, debugging, or comparing the effects of different options on the generated text to see when they diverge. If the seed is set to a value less than 0, a random seed will be used, which will result in different outputs on each run.
|
301 |
-
|
302 |
-
## Performance Tuning and Memory Options
|
303 |
-
|
304 |
-
### No Memory Mapping
|
305 |
-
|
306 |
-
- `--no-mmap`: Do not memory-map the model. By default, models are mapped into memory, which allows the system to load only the necessary parts of the model as needed. However, if the model is larger than your total amount of RAM or if your system is low on available memory, using mmap might increase the risk of pageouts, negatively impacting performance.
|
307 |
-
|
308 |
-
### Memory Float 32
|
309 |
-
|
310 |
-
- `--memory-f32`: Use 32-bit floats instead of 16-bit floats for memory key+value. This doubles the context memory requirement but does not appear to increase generation quality in a measurable way. Not recommended.
|
311 |
-
|
312 |
-
## Limitations:
|
313 |
-
|
314 |
-
- The actual implementation of llama.cpp need a `llama-state` for handle multiple contexts and clients, but this could require more powerful hardware.
|
|
|
1 |
# llama.cpp/example/server
|
2 |
|
3 |
+
This example demonstrates a simple HTTP API server to interact with llama.cpp.
|
4 |
|
5 |
+
Command line options:
|
6 |
|
7 |
+
- `--threads N`, `-t N`: Set the number of threads to use during computation.
|
8 |
+
- `-m FNAME`, `--model FNAME`: Specify the path to the LLaMA model file (e.g., `models/7B/ggml-model.bin`).
|
9 |
+
- `-m ALIAS`, `--alias ALIAS`: Set an alias for the model. The alias will be returned in API responses.
|
10 |
+
- `-c N`, `--ctx-size N`: Set the size of the prompt context. The default is 512, but LLaMA models were built with a context of 2048, which will provide better results for longer input/inference.
|
11 |
+
- `-ngl N`, `--n-gpu-layers N`: When compiled with appropriate support (currently CLBlast or cuBLAS), this option allows offloading some layers to the GPU for computation. Generally results in increased performance.
|
12 |
+
- `-mg i, --main-gpu i`: When using multiple GPUs this option controls which GPU is used for small tensors for which the overhead of splitting the computation across all GPUs is not worthwhile. The GPU in question will use slightly more VRAM to store a scratch buffer for temporary results. By default GPU 0 is used. Requires cuBLAS.
|
13 |
+
- `-ts SPLIT, --tensor-split SPLIT`: When using multiple GPUs this option controls how large tensors should be split across all GPUs. `SPLIT` is a comma-separated list of non-negative values that assigns the proportion of data that each GPU should get in order. For example, "3,2" will assign 60% of the data to GPU 0 and 40% to GPU 1. By default the data is split in proportion to VRAM but this may not be optimal for performance. Requires cuBLAS.
|
14 |
+
- `-lv, --low-vram`: Do not allocate a VRAM scratch buffer for holding temporary results. Reduces VRAM usage at the cost of performance, particularly prompt processing speed. Requires cuBLAS.
|
15 |
+
- `-b N`, `--batch-size N`: Set the batch size for prompt processing. Default: `512`.
|
16 |
+
- `--memory-f32`: Use 32-bit floats instead of 16-bit floats for memory key+value. Not recommended.
|
17 |
+
- `--mlock`: Lock the model in memory, preventing it from being swapped out when memory-mapped.
|
18 |
+
- `--no-mmap`: Do not memory-map the model. By default, models are mapped into memory, which allows the system to load only the necessary parts of the model as needed.
|
19 |
+
- `--lora FNAME`: Apply a LoRA (Low-Rank Adaptation) adapter to the model (implies --no-mmap). This allows you to adapt the pretrained model to specific tasks or domains.
|
20 |
+
- `--lora-base FNAME`: Optional model to use as a base for the layers modified by the LoRA adapter. This flag is used in conjunction with the `--lora` flag, and specifies the base model for the adaptation.
|
21 |
+
- `-to N`, `--timeout N`: Server read/write timeout in seconds. Default `600`.
|
22 |
+
- `--host`: Set the hostname or ip address to listen. Default `127.0.0.1`.
|
23 |
+
- `--port`: Set the port to listen. Default: `8080`.
|
24 |
+
|
25 |
+
## Build
|
26 |
+
|
27 |
+
Build llama.cpp with server from repository root with either make or CMake.
|
28 |
+
|
29 |
+
- Using `make`:
|
30 |
+
|
31 |
+
```bash
|
32 |
+
LLAMA_BUILD_SERVER=1 make
|
33 |
+
```
|
34 |
+
|
35 |
+
- Using `CMake`:
|
36 |
+
|
37 |
+
```bash
|
38 |
+
mkdir build-server
|
39 |
+
cd build-server
|
40 |
+
cmake -DLLAMA_BUILD_SERVER=ON ..
|
41 |
+
cmake --build . --config Release
|
42 |
+
```
|
43 |
|
44 |
## Quick Start
|
45 |
|
46 |
To get started right away, run the following command, making sure to use the correct path for the model you have:
|
47 |
|
48 |
+
### Unix-based systems (Linux, macOS, etc.):
|
49 |
|
50 |
```bash
|
51 |
+
./server -m models/7B/ggml-model.bin -c 2048
|
52 |
```
|
53 |
|
54 |
+
### Windows:
|
55 |
|
56 |
```powershell
|
57 |
+
server.exe -m models\7B\ggml-model.bin -c 2048
|
58 |
```
|
59 |
|
60 |
+
The above command will start a server that by default listens on `127.0.0.1:8080`.
|
61 |
+
You can consume the endpoints with Postman or NodeJS with axios library.
|
62 |
+
|
63 |
+
## Testing with CURL
|
64 |
+
|
65 |
+
Using [curl](https://curl.se/). On Windows `curl.exe` should be available in the base OS.
|
66 |
+
|
67 |
+
```sh
|
68 |
+
curl --request POST \
|
69 |
+
--url http://localhost:8080/completion \
|
70 |
+
--data '{"prompt": "Building a website can be done in 10 simple steps:","n_predict": 128}'
|
71 |
+
```
|
72 |
|
73 |
## Node JS Test
|
74 |
|
|
|
91 |
async function Test() {
|
92 |
let result = await axios.post("http://127.0.0.1:8080/completion", {
|
93 |
prompt,
|
|
|
94 |
n_predict: 512,
|
95 |
});
|
96 |
|
|
|
109 |
|
110 |
## API Endpoints
|
111 |
|
112 |
+
- **POST** `/completion`: Given a prompt, it returns the predicted completion.
|
113 |
|
114 |
+
*Options:*
|
115 |
|
116 |
+
`temperature`: Adjust the randomness of the generated text (default: 0.8).
|
117 |
|
118 |
+
`top_k`: Limit the next token selection to the K most probable tokens (default: 40).
|
119 |
|
120 |
+
`top_p`: Limit the next token selection to a subset of tokens with a cumulative probability above a threshold P (default: 0.9).
|
121 |
|
122 |
+
`n_predict`: Set the number of tokens to predict when generating text. **Note:** May exceed the set limit slightly if the last token is a partial multibyte character. (default: 128, -1 = infinity).
|
123 |
|
124 |
+
`n_keep`: Specify the number of tokens from the initial prompt to retain when the model resets its internal context.
|
125 |
+
By default, this value is set to 0 (meaning no tokens are kept). Use `-1` to retain all tokens from the initial prompt.
|
126 |
|
127 |
+
`stream`: It allows receiving each predicted token in real-time instead of waiting for the completion to finish. To enable this, set to `true`.
|
128 |
|
129 |
+
`prompt`: Provide a prompt. Internally, the prompt is compared, and it detects if a part has already been evaluated, and the remaining part will be evaluate.
|
130 |
|
131 |
+
`stop`: Specify a JSON array of stopping strings.
|
132 |
+
These words will not be included in the completion, so make sure to add them to the prompt for the next iteration (default: []).
|
133 |
|
134 |
+
`tfs_z`: Enable tail free sampling with parameter z (default: 1.0, 1.0 = disabled).
|
135 |
|
136 |
+
`typical_p`: Enable locally typical sampling with parameter p (default: 1.0, 1.0 = disabled).
|
137 |
|
138 |
+
`repeat_penalty`: Control the repetition of token sequences in the generated text (default: 1.1).
|
139 |
|
140 |
+
`repeat_last_n`: Last n tokens to consider for penalizing repetition (default: 64, 0 = disabled, -1 = ctx-size).
|
141 |
|
142 |
+
`penalize_nl`: Penalize newline tokens when applying the repeat penalty (default: true).
|
143 |
|
144 |
+
`presence_penalty`: Repeat alpha presence penalty (default: 0.0, 0.0 = disabled).
|
145 |
|
146 |
+
`frequency_penalty`: Repeat alpha frequency penalty (default: 0.0, 0.0 = disabled);
|
147 |
|
148 |
+
`mirostat`: Enable Mirostat sampling, controlling perplexity during text generation (default: 0, 0 = disabled, 1 = Mirostat, 2 = Mirostat 2.0).
|
149 |
|
150 |
+
`mirostat_tau`: Set the Mirostat target entropy, parameter tau (default: 5.0).
|
151 |
|
152 |
+
`mirostat_eta`: Set the Mirostat learning rate, parameter eta (default: 0.1).
|
153 |
|
154 |
+
`seed`: Set the random number generator (RNG) seed (default: -1, < 0 = random seed).
|
155 |
|
156 |
+
`ignore_eos`: Ignore end of stream token and continue generating (default: false).
|
157 |
|
158 |
+
`logit_bias`: Modify the likelihood of a token appearing in the generated text completion. For example, use `"logit_bias": [[15043,1.0]]` to increase the likelihood of the token 'Hello', or `"logit_bias": [[15043,-1.0]]` to decrease its likelihood. Setting the value to false, `"logit_bias": [[15043,false]]` ensures that the token `Hello` is never produced (default: []).
|
159 |
|
160 |
+
- **POST** `/tokenize`: Tokenize a given text.
|
161 |
|
162 |
+
*Options:*
|
163 |
|
164 |
+
`content`: Set the text to tokenize.
|
165 |
|
166 |
## More examples
|
167 |
|
168 |
### Interactive mode
|
169 |
|
170 |
+
Check the sample in [chat.mjs](chat.mjs).
|
171 |
+
Run with NodeJS version 16 or later:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
172 |
|
173 |
+
```sh
|
174 |
+
node chat.mjs
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
```
|
176 |
|
177 |
+
Another sample in [chat.sh](chat.sh).
|
178 |
+
Requires [bash](https://www.gnu.org/software/bash/), [curl](https://curl.se) and [jq](https://jqlang.github.io/jq/).
|
179 |
+
Run with bash:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
180 |
|
181 |
+
```sh
|
182 |
+
bash chat.sh
|
183 |
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
examples/server/chat.mjs
ADDED
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import * as readline from 'node:readline'
|
2 |
+
import { stdin, stdout } from 'node:process'
|
3 |
+
|
4 |
+
const API_URL = 'http://127.0.0.1:8080'
|
5 |
+
|
6 |
+
const chat = [
|
7 |
+
{
|
8 |
+
human: "Hello, Assistant.",
|
9 |
+
assistant: "Hello. How may I help you today?"
|
10 |
+
},
|
11 |
+
{
|
12 |
+
human: "Please tell me the largest city in Europe.",
|
13 |
+
assistant: "Sure. The largest city in Europe is Moscow, the capital of Russia."
|
14 |
+
},
|
15 |
+
]
|
16 |
+
|
17 |
+
const instruction = `A chat between a curious human and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the human's questions.`
|
18 |
+
|
19 |
+
function format_prompt(question) {
|
20 |
+
return `${instruction}\n${
|
21 |
+
chat.map(m =>`### Human: ${m.human}\n### Assistant: ${m.assistant}`).join("\n")
|
22 |
+
}\n### Human: ${question}\n### Assistant:`
|
23 |
+
}
|
24 |
+
|
25 |
+
async function tokenize(content) {
|
26 |
+
const result = await fetch(`${API_URL}/tokenize`, {
|
27 |
+
method: 'POST',
|
28 |
+
body: JSON.stringify({ content })
|
29 |
+
})
|
30 |
+
|
31 |
+
if (!result.ok) {
|
32 |
+
return []
|
33 |
+
}
|
34 |
+
|
35 |
+
return await result.json().tokens
|
36 |
+
}
|
37 |
+
|
38 |
+
const n_keep = await tokenize(instruction).length
|
39 |
+
|
40 |
+
async function chat_completion(question) {
|
41 |
+
const result = await fetch(`${API_URL}/completion`, {
|
42 |
+
method: 'POST',
|
43 |
+
body: JSON.stringify({
|
44 |
+
prompt: format_prompt(question),
|
45 |
+
temperature: 0.2,
|
46 |
+
top_k: 40,
|
47 |
+
top_p: 0.9,
|
48 |
+
n_keep: n_keep,
|
49 |
+
n_predict: 256,
|
50 |
+
stop: ["\n### Human:"], // stop completion after generating this
|
51 |
+
stream: true,
|
52 |
+
})
|
53 |
+
})
|
54 |
+
|
55 |
+
if (!result.ok) {
|
56 |
+
return
|
57 |
+
}
|
58 |
+
|
59 |
+
let answer = ''
|
60 |
+
|
61 |
+
for await (var chunk of result.body) {
|
62 |
+
const t = Buffer.from(chunk).toString('utf8')
|
63 |
+
if (t.startsWith('data: ')) {
|
64 |
+
const message = JSON.parse(t.substring(6))
|
65 |
+
answer += message.content
|
66 |
+
process.stdout.write(message.content)
|
67 |
+
if (message.stop) {
|
68 |
+
if (message.truncated) {
|
69 |
+
chat.shift()
|
70 |
+
}
|
71 |
+
break
|
72 |
+
}
|
73 |
+
}
|
74 |
+
}
|
75 |
+
|
76 |
+
process.stdout.write('\n')
|
77 |
+
chat.push({ human: question, assistant: answer.trimStart() })
|
78 |
+
}
|
79 |
+
|
80 |
+
const rl = readline.createInterface({ input: stdin, output: stdout });
|
81 |
+
|
82 |
+
const readlineQuestion = (rl, query, options) => new Promise((resolve, reject) => {
|
83 |
+
rl.question(query, options, resolve)
|
84 |
+
});
|
85 |
+
|
86 |
+
while(true) {
|
87 |
+
const question = await readlineQuestion(rl, '> ')
|
88 |
+
await chat_completion(question)
|
89 |
+
}
|
examples/server/chat.sh
ADDED
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/bin/bash
|
2 |
+
|
3 |
+
API_URL="${API_URL:-http://127.0.0.1:8080}"
|
4 |
+
|
5 |
+
CHAT=(
|
6 |
+
"Hello, Assistant."
|
7 |
+
"Hello. How may I help you today?"
|
8 |
+
"Please tell me the largest city in Europe."
|
9 |
+
"Sure. The largest city in Europe is Moscow, the capital of Russia."
|
10 |
+
)
|
11 |
+
|
12 |
+
INSTRUCTION="A chat between a curious human and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the human's questions."
|
13 |
+
|
14 |
+
trim() {
|
15 |
+
shopt -s extglob
|
16 |
+
set -- "${1##+([[:space:]])}"
|
17 |
+
printf "%s" "${1%%+([[:space:]])}"
|
18 |
+
}
|
19 |
+
|
20 |
+
trim_trailing() {
|
21 |
+
shopt -s extglob
|
22 |
+
printf "%s" "${1%%+([[:space:]])}"
|
23 |
+
}
|
24 |
+
|
25 |
+
format_prompt() {
|
26 |
+
echo -n "${INSTRUCTION}"
|
27 |
+
printf "\n### Human: %s\n### Assistant: %s" "${CHAT[@]}" "$1"
|
28 |
+
}
|
29 |
+
|
30 |
+
tokenize() {
|
31 |
+
curl \
|
32 |
+
--silent \
|
33 |
+
--request POST \
|
34 |
+
--url "${API_URL}/tokenize" \
|
35 |
+
--data-raw "$(jq -ns --arg content "$1" '{content:$content}')" \
|
36 |
+
| jq '.tokens[]'
|
37 |
+
}
|
38 |
+
|
39 |
+
N_KEEP=$(tokenize "${INSTRUCTION}" | wc -l)
|
40 |
+
|
41 |
+
chat_completion() {
|
42 |
+
PROMPT="$(trim_trailing "$(format_prompt "$1")")"
|
43 |
+
DATA="$(echo -n "$PROMPT" | jq -Rs --argjson n_keep $N_KEEP '{
|
44 |
+
prompt: .,
|
45 |
+
temperature: 0.2,
|
46 |
+
top_k: 40,
|
47 |
+
top_p: 0.9,
|
48 |
+
n_keep: $n_keep,
|
49 |
+
n_predict: 256,
|
50 |
+
stop: ["\n### Human:"],
|
51 |
+
stream: true
|
52 |
+
}')"
|
53 |
+
|
54 |
+
ANSWER=''
|
55 |
+
|
56 |
+
while IFS= read -r LINE; do
|
57 |
+
if [[ $LINE = data:* ]]; then
|
58 |
+
CONTENT="$(echo "${LINE:5}" | jq -r '.content')"
|
59 |
+
printf "%s" "${CONTENT}"
|
60 |
+
ANSWER+="${CONTENT}"
|
61 |
+
fi
|
62 |
+
done < <(curl \
|
63 |
+
--silent \
|
64 |
+
--no-buffer \
|
65 |
+
--request POST \
|
66 |
+
--url "${API_URL}/completion" \
|
67 |
+
--data-raw "${DATA}")
|
68 |
+
|
69 |
+
printf "\n"
|
70 |
+
|
71 |
+
CHAT+=("$1" "$(trim "$ANSWER")")
|
72 |
+
}
|
73 |
+
|
74 |
+
while true; do
|
75 |
+
read -r -e -p "> " QUESTION
|
76 |
+
chat_completion "${QUESTION}"
|
77 |
+
done
|
examples/server/server.cpp
CHANGED
@@ -1,790 +1,928 @@
|
|
1 |
-
#include <httplib.h>
|
2 |
-
#include <json.hpp>
|
3 |
#include "common.h"
|
4 |
#include "llama.h"
|
|
|
5 |
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
};
|
11 |
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
num_tokens_predicted = 0;
|
40 |
-
generated_text = "";
|
41 |
-
}
|
42 |
-
|
43 |
-
bool loadModel(gpt_params params_)
|
44 |
-
{
|
45 |
-
params = params_;
|
46 |
-
ctx = llama_init_from_gpt_params(params);
|
47 |
-
if (ctx == NULL)
|
48 |
-
{
|
49 |
-
fprintf(stderr, "%s: error: unable to load model\n", __func__);
|
50 |
-
return false;
|
51 |
-
}
|
52 |
-
// determine newline token
|
53 |
-
llama_token_newline = ::llama_tokenize(ctx, "\n", false);
|
54 |
-
last_n_tokens.resize(params.n_ctx);
|
55 |
-
std::fill(last_n_tokens.begin(), last_n_tokens.end(), 0);
|
56 |
-
return true;
|
57 |
-
}
|
58 |
-
|
59 |
-
bool loadPrompt() {
|
60 |
-
params.prompt.insert(0, 1, ' '); // always add a first space
|
61 |
-
std::vector<llama_token> prompt_tokens = ::llama_tokenize(ctx, params.prompt, true);
|
62 |
-
// compare the evaluated prompt with the new prompt
|
63 |
-
int new_prompt_len = 0;
|
64 |
-
for (size_t i = 0; i < prompt_tokens.size(); i++) {
|
65 |
-
if (i < processed_tokens.size() &&
|
66 |
-
processed_tokens[i] == prompt_tokens[i])
|
67 |
-
{
|
68 |
-
continue;
|
69 |
-
}
|
70 |
-
else
|
71 |
-
{
|
72 |
-
embd_inp.push_back(prompt_tokens[i]);
|
73 |
-
if(new_prompt_len == 0) {
|
74 |
-
if(int32_t(i) - 1 < n_past) {
|
75 |
-
processed_tokens.erase(processed_tokens.begin() + i, processed_tokens.end());
|
76 |
-
}
|
77 |
-
// Evaluate the new fragment prompt from the last token processed.
|
78 |
-
n_past = processed_tokens.size();
|
79 |
}
|
80 |
-
new_prompt_len ++;
|
81 |
-
}
|
82 |
-
}
|
83 |
-
if(n_past > 0 && params.interactive) {
|
84 |
-
n_remain -= new_prompt_len;
|
85 |
}
|
86 |
-
|
87 |
-
|
88 |
-
|
|
|
|
|
|
|
|
|
|
|
89 |
}
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
|
|
|
|
|
|
102 |
}
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
}
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
130 |
}
|
131 |
-
|
132 |
-
|
|
|
|
|
133 |
}
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
const float tfs_z = params.tfs_z;
|
142 |
-
const float typical_p = params.typical_p;
|
143 |
-
const int32_t repeat_last_n = params.repeat_last_n < 0 ? params.n_ctx : params.repeat_last_n;
|
144 |
-
const float repeat_penalty = params.repeat_penalty;
|
145 |
-
const float alpha_presence = params.presence_penalty;
|
146 |
-
const float alpha_frequency = params.frequency_penalty;
|
147 |
-
const int mirostat = params.mirostat;
|
148 |
-
const float mirostat_tau = params.mirostat_tau;
|
149 |
-
const float mirostat_eta = params.mirostat_eta;
|
150 |
-
const bool penalize_nl = params.penalize_nl;
|
151 |
-
llama_token id = 0;
|
152 |
-
{
|
153 |
-
auto logits = llama_get_logits(ctx);
|
154 |
-
auto n_vocab = llama_n_vocab(ctx);
|
155 |
-
|
156 |
-
// Apply params.logit_bias map
|
157 |
-
for (auto it = params.logit_bias.begin(); it != params.logit_bias.end(); it++)
|
158 |
-
{
|
159 |
-
logits[it->first] += it->second;
|
160 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
161 |
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
|
|
167 |
}
|
168 |
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
last_n_tokens.data() + last_n_tokens.size() - last_n_repeat,
|
176 |
-
last_n_repeat, repeat_penalty);
|
177 |
-
llama_sample_frequency_and_presence_penalties(ctx, &candidates_p,
|
178 |
-
last_n_tokens.data() + last_n_tokens.size() - last_n_repeat,
|
179 |
-
last_n_repeat, alpha_frequency, alpha_presence);
|
180 |
-
if (!penalize_nl)
|
181 |
-
{
|
182 |
-
logits[llama_token_nl()] = nl_logit;
|
183 |
}
|
184 |
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
189 |
}
|
190 |
-
|
191 |
-
{
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
// Temperature sampling
|
208 |
-
llama_sample_tail_free(ctx, &candidates_p, tfs_z, 1);
|
209 |
-
llama_sample_typical(ctx, &candidates_p, typical_p, 1);
|
210 |
-
llama_sample_top_p(ctx, &candidates_p, top_p, 1);
|
211 |
-
llama_sample_temperature(ctx, &candidates_p, temp);
|
212 |
-
id = llama_sample_token(ctx, &candidates_p);
|
213 |
-
}
|
214 |
}
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
226 |
{
|
227 |
-
|
228 |
-
|
229 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
230 |
}
|
231 |
-
}
|
232 |
|
233 |
-
|
234 |
-
|
235 |
-
for (auto id : embd)
|
236 |
-
{
|
237 |
result = id;
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
{
|
244 |
-
// some user input remains from prompt or interaction, forward it to processing
|
245 |
-
while ((int)embd_inp.size() > n_consumed)
|
246 |
-
{
|
247 |
-
embd.push_back(embd_inp[n_consumed]);
|
248 |
-
last_n_tokens.erase(last_n_tokens.begin());
|
249 |
-
last_n_tokens.push_back(embd_inp[n_consumed]);
|
250 |
-
processed_tokens.push_back(embd_inp[n_consumed]);
|
251 |
-
++n_consumed;
|
252 |
-
if ((int)embd.size() >= params.n_batch)
|
253 |
-
{
|
254 |
-
break;
|
255 |
-
}
|
256 |
-
}
|
257 |
-
}
|
258 |
-
if (params.interactive && (int)embd_inp.size() <= n_consumed)
|
259 |
-
{
|
260 |
-
// check for reverse prompt
|
261 |
-
if (params.antiprompt.size())
|
262 |
-
{
|
263 |
-
std::string last_output;
|
264 |
-
for (auto id : last_n_tokens)
|
265 |
-
{
|
266 |
-
last_output += llama_token_to_str(ctx, id);
|
267 |
-
}
|
268 |
-
has_next_token = true;
|
269 |
-
// Check if each of the reverse prompts appears at the end of the output.
|
270 |
-
for (std::string &antiprompt : params.antiprompt)
|
271 |
-
{
|
272 |
-
if (last_output.find(antiprompt.c_str(), last_output.length() - antiprompt.length(), antiprompt.length()) != std::string::npos)
|
273 |
-
{
|
274 |
has_next_token = false;
|
|
|
|
|
275 |
return result;
|
276 |
-
}
|
277 |
}
|
278 |
-
}
|
279 |
-
if (n_past > 0)
|
280 |
-
{
|
281 |
-
has_next_token = true;
|
282 |
-
}
|
283 |
-
}
|
284 |
|
285 |
-
|
286 |
-
|
287 |
}
|
288 |
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
{
|
299 |
-
llama_token token = nextToken();
|
300 |
-
if (token == -1) {
|
301 |
-
return "";
|
302 |
-
}
|
303 |
-
tokens_predicted.clear();
|
304 |
-
tokens_predicted.push_back(token);
|
305 |
-
|
306 |
-
// Avoid add the no show words to the response
|
307 |
-
for (std::vector<llama_token> word_tokens : no_show_words)
|
308 |
-
{
|
309 |
-
size_t match_token = 1;
|
310 |
-
if (tokens_predicted.front() == word_tokens.front())
|
311 |
-
{
|
312 |
-
bool execute_matching = true;
|
313 |
-
if (tokens_predicted.size() > 1) { // if previus tokens had been tested
|
314 |
-
for (size_t i = 1; i < word_tokens.size(); i++)
|
315 |
-
{
|
316 |
-
if (i >= tokens_predicted.size()) {
|
317 |
-
match_token = i;
|
318 |
-
break;
|
319 |
}
|
320 |
-
|
321 |
-
|
322 |
-
continue;
|
323 |
}
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
|
|
|
|
|
|
|
|
328 |
}
|
329 |
-
}
|
330 |
-
}
|
331 |
-
while (execute_matching) {
|
332 |
-
if (match_token == word_tokens.size()) {
|
333 |
-
return "";
|
334 |
-
}
|
335 |
-
token = nextToken();
|
336 |
-
tokens_predicted.push_back(token);
|
337 |
-
if (token == word_tokens[match_token])
|
338 |
-
{ // the token follow the sequence
|
339 |
-
match_token++;
|
340 |
-
}
|
341 |
-
else if (match_token < word_tokens.size())
|
342 |
-
{ // no complete all word sequence
|
343 |
-
break;
|
344 |
-
}
|
345 |
}
|
346 |
-
|
347 |
-
}
|
348 |
-
if(as_loop) {
|
349 |
-
generated_text = "";
|
350 |
-
}
|
351 |
-
for (llama_token tkn : tokens_predicted)
|
352 |
-
{
|
353 |
-
generated_text += llama_token_to_str(ctx, tkn);
|
354 |
-
}
|
355 |
-
return generated_text;
|
356 |
-
}
|
357 |
-
|
358 |
-
std::vector<float> embedding(std::string content, int threads) {
|
359 |
-
content.insert(0, 1, ' ');
|
360 |
-
std::vector<llama_token> tokens = ::llama_tokenize(ctx, content, true);
|
361 |
-
if (tokens.size() > 0)
|
362 |
-
{
|
363 |
-
if (llama_eval(ctx, tokens.data(), tokens.size(), 0, threads))
|
364 |
-
{
|
365 |
-
fprintf(stderr, "%s : failed to eval\n", __func__);
|
366 |
-
std::vector<float> embeddings_;
|
367 |
-
return embeddings_;
|
368 |
-
}
|
369 |
}
|
370 |
-
const int n_embd = llama_n_embd(ctx);
|
371 |
-
const auto embeddings = llama_get_embeddings(ctx);
|
372 |
-
std::vector<float> embeddings_(embeddings, embeddings + n_embd);
|
373 |
-
return embeddings_;
|
374 |
-
}
|
375 |
-
};
|
376 |
|
377 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
378 |
|
379 |
-
|
|
|
|
|
|
|
380 |
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
fprintf(stderr, "\n");
|
385 |
-
fprintf(stderr, "options:\n");
|
386 |
-
fprintf(stderr, " -h, --help show this help message and exit\n");
|
387 |
-
fprintf(stderr, " -s SEED, --seed SEED RNG seed (default: -1, use random seed for < 0)\n");
|
388 |
-
fprintf(stderr, " -c N, --ctx-size N size of the prompt context (default: %d)\n", params.n_ctx);
|
389 |
-
fprintf(stderr, " --memory-f32 use f32 instead of f16 for memory key+value (default: disabled)\n");
|
390 |
-
fprintf(stderr, " not recommended: doubles context memory required and no measurable increase in quality\n");
|
391 |
-
fprintf(stderr, " --embedding enable embedding mode\n");
|
392 |
-
fprintf(stderr, " --keep number of tokens to keep from the initial prompt (default: %d, -1 = all)\n", params.n_keep);
|
393 |
-
if (llama_mlock_supported())
|
394 |
-
{
|
395 |
-
fprintf(stderr, " --mlock force system to keep model in RAM rather than swapping or compressing\n");
|
396 |
-
}
|
397 |
-
if (llama_mmap_supported())
|
398 |
-
{
|
399 |
-
fprintf(stderr, " --no-mmap do not memory-map model (slower load but may reduce pageouts if not using mlock)\n");
|
400 |
-
}
|
401 |
-
#ifdef LLAMA_SUPPORTS_GPU_OFFLOAD
|
402 |
-
fprintf(stderr, " -ngl N, --n-gpu-layers N\n");
|
403 |
-
fprintf(stderr, " number of layers to store in VRAM\n");
|
404 |
-
fprintf(stderr, " -ts SPLIT --tensor-split SPLIT\n");
|
405 |
-
fprintf(stderr, " how to split tensors across multiple GPUs, comma-separated list of proportions, e.g. 3,1\n");
|
406 |
-
fprintf(stderr, " how to split tensors across multiple GPUs, comma-separated list of proportions, e.g. 3,1\n");
|
407 |
-
fprintf(stderr, " -mg i, --main-gpu i the GPU to use for scratch and small tensors\n" );
|
408 |
-
#endif
|
409 |
-
fprintf(stderr, " -m FNAME, --model FNAME\n");
|
410 |
-
fprintf(stderr, " model path (default: %s)\n", params.model.c_str());
|
411 |
-
fprintf(stderr, " -a ALIAS, --alias ALIAS\n");
|
412 |
-
fprintf(stderr, " set an alias for the model, will be added as `model` field in completion response\n");
|
413 |
-
fprintf(stderr, " --host ip address to listen (default 127.0.0.1)\n");
|
414 |
-
fprintf(stderr, " --port PORT port to listen (default 8080)\n");
|
415 |
-
fprintf(stderr, "\n");
|
416 |
-
}
|
417 |
|
418 |
-
|
419 |
-
{
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
invalid_param = true;
|
432 |
-
break;
|
433 |
-
}
|
434 |
-
sparams.port = std::stoi(argv[i]);
|
435 |
-
}
|
436 |
-
else if (arg == "--host")
|
437 |
-
{
|
438 |
-
if (++i >= argc)
|
439 |
-
{
|
440 |
-
invalid_param = true;
|
441 |
-
break;
|
442 |
-
}
|
443 |
-
sparams.hostname = argv[i];
|
444 |
-
}
|
445 |
-
else if (arg == "-s" || arg == "--seed")
|
446 |
-
{
|
447 |
-
#if defined(GGML_USE_CUBLAS)
|
448 |
-
fprintf(stderr, "WARNING: when using cuBLAS generation results are NOT guaranteed to be reproducible.\n");
|
449 |
-
#endif
|
450 |
-
if (++i >= argc)
|
451 |
-
{
|
452 |
-
invalid_param = true;
|
453 |
-
break;
|
454 |
-
}
|
455 |
-
params.seed = std::stoi(argv[i]);
|
456 |
-
}
|
457 |
-
else if (arg == "-m" || arg == "--model")
|
458 |
-
{
|
459 |
-
if (++i >= argc)
|
460 |
-
{
|
461 |
-
invalid_param = true;
|
462 |
-
break;
|
463 |
-
}
|
464 |
-
params.model = argv[i];
|
465 |
-
}
|
466 |
-
else if (arg == "-a" || arg == "--alias")
|
467 |
-
{
|
468 |
-
if (++i >= argc)
|
469 |
-
{
|
470 |
-
invalid_param = true;
|
471 |
-
break;
|
472 |
-
}
|
473 |
-
params.model_alias = argv[i];
|
474 |
-
}
|
475 |
-
else if (arg == "--embedding")
|
476 |
-
{
|
477 |
-
params.embedding = true;
|
478 |
}
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
|
|
|
|
|
|
492 |
}
|
493 |
-
|
494 |
-
|
495 |
-
params.memory_f16 = false;
|
496 |
}
|
497 |
-
else if (arg == "--gpu-layers" || arg == "-ngl" || arg == "--n-gpu-layers")
|
498 |
-
{
|
499 |
-
if (++i >= argc)
|
500 |
-
{
|
501 |
-
invalid_param = true;
|
502 |
-
break;
|
503 |
-
}
|
504 |
#ifdef LLAMA_SUPPORTS_GPU_OFFLOAD
|
505 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
506 |
#else
|
507 |
-
|
508 |
-
|
509 |
#endif
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
break;
|
517 |
-
}
|
518 |
#ifdef GGML_USE_CUBLAS
|
519 |
-
|
520 |
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
532 |
}
|
533 |
-
else
|
534 |
{
|
535 |
-
|
536 |
-
|
537 |
-
}
|
538 |
#else
|
539 |
-
|
540 |
#endif // GGML_USE_CUBLAS
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
break;
|
548 |
-
}
|
549 |
#ifdef GGML_USE_CUBLAS
|
550 |
-
|
551 |
#else
|
552 |
-
|
553 |
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
554 |
}
|
555 |
-
|
556 |
-
{
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
}
|
561 |
-
}
|
562 |
-
|
563 |
-
if (invalid_param)
|
564 |
-
{
|
565 |
-
fprintf(stderr, "error: invalid parameter for argument: %s\n", arg.c_str());
|
566 |
-
server_print_usage(argc, argv, default_params);
|
567 |
-
exit(1);
|
568 |
-
}
|
569 |
-
return true;
|
570 |
}
|
571 |
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
629 |
}
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
|
|
|
|
637 |
}
|
638 |
-
|
639 |
-
|
640 |
}
|
641 |
|
642 |
-
|
643 |
-
{
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
if (server_params_parse(argc, argv, sparams, params) == false)
|
653 |
-
{
|
654 |
-
return 1;
|
655 |
-
}
|
656 |
-
|
657 |
-
if (params.seed <= 0)
|
658 |
-
{
|
659 |
-
params.seed = time(NULL);
|
660 |
-
}
|
661 |
-
|
662 |
-
fprintf(stderr, "%s: seed = %d\n", __func__, params.seed);
|
663 |
-
|
664 |
-
// load the model
|
665 |
-
if (!llama.loadModel(params))
|
666 |
-
{
|
667 |
-
return 1;
|
668 |
-
}
|
669 |
-
|
670 |
-
Server svr;
|
671 |
-
|
672 |
-
svr.Get("/", [](const Request &, Response &res)
|
673 |
-
{ res.set_content("<h1>llama.cpp server works</h1>", "text/html"); });
|
674 |
-
|
675 |
-
svr.Post("/completion", [&llama](const Request &req, Response &res)
|
676 |
-
{
|
677 |
-
if(llama.params.embedding) {
|
678 |
-
json data = {
|
679 |
-
{"status", "error"},
|
680 |
-
{"reason", "To use completion function disable embedding mode"}};
|
681 |
-
res.set_content(data.dump(), "application/json");
|
682 |
-
res.status = 400;
|
683 |
-
return;
|
684 |
-
}
|
685 |
-
|
686 |
-
llama.rewind();
|
687 |
-
|
688 |
-
if(parse_options_completion(json::parse(req.body), llama, res) == false){
|
689 |
-
return;
|
690 |
-
}
|
691 |
-
|
692 |
-
if (!llama.loadPrompt())
|
693 |
-
{
|
694 |
-
json data = {
|
695 |
-
{"status", "error"},
|
696 |
-
{"reason", "Context too long, please be more specific"}};
|
697 |
-
res.set_content(data.dump(), "application/json");
|
698 |
-
res.status = 400;
|
699 |
-
return;
|
700 |
-
}
|
701 |
-
|
702 |
-
llama.beginCompletion();
|
703 |
-
if(llama.as_loop) {
|
704 |
-
json data = {
|
705 |
-
{"status", "done" } };
|
706 |
-
return res.set_content(data.dump(), "application/json");
|
707 |
-
} else {
|
708 |
-
// loop inference until finish completion
|
709 |
-
while (llama.has_next_token)
|
710 |
-
{
|
711 |
-
llama.doCompletion();
|
712 |
-
}
|
713 |
-
try
|
714 |
-
{
|
715 |
-
json data = {
|
716 |
-
{"model", llama.params.model_alias },
|
717 |
-
{"content", llama.generated_text },
|
718 |
-
{"tokens_predicted", llama.num_tokens_predicted}};
|
719 |
-
return res.set_content(data.dump(), "application/json");
|
720 |
-
}
|
721 |
-
catch (const json::exception &e)
|
722 |
-
{
|
723 |
-
// Some tokens have bad UTF-8 strings, the json parser is very sensitive
|
724 |
-
json data = {
|
725 |
-
{"content", "Bad encoding token"},
|
726 |
-
{"tokens_predicted", 0}};
|
727 |
-
return res.set_content(data.dump(), "application/json");
|
728 |
-
}
|
729 |
-
} });
|
730 |
-
|
731 |
-
svr.Post("/tokenize", [&llama](const Request &req, Response &res)
|
732 |
-
{
|
733 |
-
json body = json::parse(req.body);
|
734 |
-
json data = {
|
735 |
-
{"tokens", ::llama_tokenize(llama.ctx, body["content"].get<std::string>(), false) } };
|
736 |
-
return res.set_content(data.dump(), "application/json");
|
737 |
-
});
|
738 |
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
json data = {
|
744 |
-
{"embedding", empty}};
|
745 |
-
fprintf(stderr, "[llama-server] : You need enable embedding mode adding: --embedding option\n");
|
746 |
-
return res.set_content(data.dump(), "application/json");
|
747 |
-
}
|
748 |
-
json body = json::parse(req.body);
|
749 |
-
std::string content = body["content"].get<std::string>();
|
750 |
-
int threads = body["threads"].get<int>();
|
751 |
-
json data = {
|
752 |
-
{"embedding", llama.embedding(content, threads) } };
|
753 |
-
return res.set_content(data.dump(), "application/json");
|
754 |
-
});
|
755 |
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
761 |
}
|
762 |
-
|
763 |
-
if (
|
764 |
-
llama.
|
765 |
-
} else {
|
766 |
-
result = llama.doCompletion(); // inference next token
|
767 |
}
|
768 |
-
|
769 |
-
|
770 |
-
|
771 |
-
{"stop", !llama.has_next_token }};
|
772 |
-
return res.set_content(data.dump(), "application/json");
|
773 |
-
} catch (const json::exception &e) {
|
774 |
-
// Some tokens have bad UTF-8 strings, the json parser is very sensitive
|
775 |
-
json data = {
|
776 |
-
{"content", "" },
|
777 |
-
{"stop", !llama.has_next_token }};
|
778 |
-
return res.set_content(data.dump(), "application/json");
|
779 |
}
|
780 |
-
});
|
781 |
|
782 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
783 |
|
784 |
-
|
785 |
-
|
786 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
787 |
|
788 |
-
|
789 |
-
svr.listen(sparams.hostname, sparams.port);
|
790 |
}
|
|
|
|
|
|
|
1 |
#include "common.h"
|
2 |
#include "llama.h"
|
3 |
+
#include "build-info.h"
|
4 |
|
5 |
+
// single thread
|
6 |
+
#define CPPHTTPLIB_THREAD_POOL_COUNT 1
|
7 |
+
#ifndef NDEBUG
|
8 |
+
// crash the server in debug mode, otherwise send an http 500 error
|
9 |
+
#define CPPHTTPLIB_NO_EXCEPTIONS 1
|
10 |
+
#endif
|
11 |
+
|
12 |
+
#include "httplib.h"
|
13 |
+
#include "json.hpp"
|
14 |
+
|
15 |
+
#ifndef SERVER_VERBOSE
|
16 |
+
#define SERVER_VERBOSE 1
|
17 |
+
#endif
|
18 |
+
|
19 |
+
using namespace httplib;
|
20 |
+
using json = nlohmann::json;
|
21 |
+
|
22 |
+
struct server_params {
|
23 |
+
std::string hostname = "127.0.0.1";
|
24 |
+
int32_t port = 8080;
|
25 |
+
int32_t read_timeout = 600;
|
26 |
+
int32_t write_timeout = 600;
|
27 |
};
|
28 |
|
29 |
+
static size_t common_part(const std::vector<llama_token> & a, const std::vector<llama_token> & b) {
|
30 |
+
size_t i;
|
31 |
+
for (i = 0; i < a.size() && i < b.size() && a[i] == b[i]; i++) {}
|
32 |
+
return i;
|
33 |
+
}
|
34 |
+
|
35 |
+
enum stop_type {
|
36 |
+
STOP_FULL,
|
37 |
+
STOP_PARTIAL,
|
38 |
+
};
|
39 |
+
|
40 |
+
static bool ends_with(const std::string & str, const std::string & suffix) {
|
41 |
+
return str.size() >= suffix.size() &&
|
42 |
+
0 == str.compare(str.size() - suffix.size(), suffix.size(), suffix);
|
43 |
+
}
|
44 |
+
|
45 |
+
static size_t find_partial_stop_string(const std::string & stop,
|
46 |
+
const std::string & text) {
|
47 |
+
if (!text.empty() && !stop.empty()) {
|
48 |
+
const char text_last_char = text.back();
|
49 |
+
for (int64_t char_index = stop.size() - 1; char_index >= 0; char_index--) {
|
50 |
+
if (stop[char_index] == text_last_char) {
|
51 |
+
const std::string current_partial = stop.substr(0, char_index + 1);
|
52 |
+
if (ends_with(text, current_partial)) {
|
53 |
+
return text.size() - char_index - 1;
|
54 |
+
}
|
55 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
}
|
|
|
|
|
|
|
|
|
|
|
57 |
}
|
58 |
+
return std::string::npos;
|
59 |
+
}
|
60 |
+
|
61 |
+
template<class Iter>
|
62 |
+
static std::string tokens_to_str(llama_context * ctx, Iter begin, Iter end) {
|
63 |
+
std::string ret;
|
64 |
+
for (; begin != end; ++begin) {
|
65 |
+
ret += llama_token_to_str(ctx, *begin);
|
66 |
}
|
67 |
+
return ret;
|
68 |
+
}
|
69 |
+
|
70 |
+
static void server_log(const char * level, const char * function, int line,
|
71 |
+
const char * message, const nlohmann::ordered_json & extra) {
|
72 |
+
nlohmann::ordered_json log {
|
73 |
+
{ "timestamp", time(nullptr) },
|
74 |
+
{ "level", level },
|
75 |
+
{ "function", function },
|
76 |
+
{ "line", line },
|
77 |
+
{ "message", message },
|
78 |
+
};
|
79 |
+
|
80 |
+
if (!extra.empty()) {
|
81 |
+
log.merge_patch(extra);
|
82 |
}
|
83 |
+
|
84 |
+
const std::string str = log.dump(-1, ' ', false, json::error_handler_t::replace);
|
85 |
+
fprintf(stdout, "%.*s\n", (int)str.size(), str.data());
|
86 |
+
fflush(stdout);
|
87 |
+
}
|
88 |
+
|
89 |
+
static bool server_verbose = false;
|
90 |
+
|
91 |
+
#if SERVER_VERBOSE != 1
|
92 |
+
# define LOG_VERBOSE(MSG, ...)
|
93 |
+
#else
|
94 |
+
# define LOG_VERBOSE(MSG, ...) \
|
95 |
+
do { \
|
96 |
+
if (server_verbose) { \
|
97 |
+
server_log("VERBOSE", __func__, __LINE__, MSG, __VA_ARGS__); \
|
98 |
+
} \
|
99 |
+
} while(0)
|
100 |
+
#endif
|
101 |
+
|
102 |
+
#define LOG_ERROR(MSG, ...) server_log("ERROR", __func__, __LINE__, MSG, __VA_ARGS__)
|
103 |
+
#define LOG_WARNING(MSG, ...) server_log("WARNING", __func__, __LINE__, MSG, __VA_ARGS__)
|
104 |
+
#define LOG_INFO(MSG, ...) server_log("INFO", __func__, __LINE__, MSG, __VA_ARGS__)
|
105 |
+
|
106 |
+
struct llama_server_context {
|
107 |
+
bool stream = false;
|
108 |
+
bool has_next_token = false;
|
109 |
+
std::string generated_text;
|
110 |
+
|
111 |
+
size_t num_tokens_predicted = 0;
|
112 |
+
size_t n_past = 0;
|
113 |
+
size_t n_remain = 0;
|
114 |
+
|
115 |
+
std::vector<llama_token> embd;
|
116 |
+
std::vector<llama_token> last_n_tokens;
|
117 |
+
|
118 |
+
llama_context * ctx = nullptr;
|
119 |
+
gpt_params params;
|
120 |
+
|
121 |
+
bool truncated = false;
|
122 |
+
bool stopped_eos = false;
|
123 |
+
bool stopped_word = false;
|
124 |
+
bool stopped_limit = false;
|
125 |
+
std::string stopping_word;
|
126 |
+
int32_t multibyte_pending = 0;
|
127 |
+
|
128 |
+
~llama_server_context() {
|
129 |
+
if (ctx) {
|
130 |
+
llama_free(ctx);
|
131 |
+
ctx = nullptr;
|
132 |
}
|
133 |
+
}
|
134 |
+
|
135 |
+
void rewind() {
|
136 |
+
params.antiprompt.clear();
|
137 |
+
num_tokens_predicted = 0;
|
138 |
+
generated_text = "";
|
139 |
+
generated_text.reserve(params.n_ctx);
|
140 |
+
truncated = false;
|
141 |
+
stopped_eos = false;
|
142 |
+
stopped_word = false;
|
143 |
+
stopped_limit = false;
|
144 |
+
stopping_word = "";
|
145 |
+
multibyte_pending = 0;
|
146 |
+
|
147 |
+
n_remain = 0;
|
148 |
+
n_past = 0;
|
149 |
+
}
|
150 |
+
|
151 |
+
bool loadModel(const gpt_params & params_) {
|
152 |
+
params = params_;
|
153 |
+
ctx = llama_init_from_gpt_params(params);
|
154 |
+
if (ctx == nullptr) {
|
155 |
+
LOG_ERROR("unable to load model", { { "model", params_.model } });
|
156 |
+
return false;
|
157 |
}
|
158 |
+
|
159 |
+
last_n_tokens.resize(params.n_ctx);
|
160 |
+
std::fill(last_n_tokens.begin(), last_n_tokens.end(), 0);
|
161 |
+
return true;
|
162 |
}
|
163 |
+
|
164 |
+
void loadPrompt() {
|
165 |
+
params.prompt.insert(0, 1, ' '); // always add a first space
|
166 |
+
std::vector<llama_token> prompt_tokens = ::llama_tokenize(ctx, params.prompt, true);
|
167 |
+
|
168 |
+
if (params.n_keep < 0) {
|
169 |
+
params.n_keep = (int)prompt_tokens.size();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
170 |
}
|
171 |
+
params.n_keep = std::min(params.n_ctx - 4, params.n_keep);
|
172 |
+
|
173 |
+
// if input prompt is too big, truncate like normal
|
174 |
+
if (prompt_tokens.size() >= (size_t)params.n_ctx) {
|
175 |
+
const int n_left = (params.n_ctx - params.n_keep) / 2;
|
176 |
+
std::vector<llama_token> new_tokens(prompt_tokens.begin(), prompt_tokens.begin() + params.n_keep);
|
177 |
+
const int erased_blocks = (prompt_tokens.size() - params.n_keep - n_left - 1) / n_left;
|
178 |
+
new_tokens.insert(new_tokens.end(), prompt_tokens.begin() + params.n_keep + erased_blocks * n_left, prompt_tokens.end());
|
179 |
+
std::copy(prompt_tokens.end() - params.n_ctx, prompt_tokens.end(), last_n_tokens.begin());
|
180 |
+
|
181 |
+
LOG_VERBOSE("input truncated", {
|
182 |
+
{ "n_ctx", params.n_ctx },
|
183 |
+
{ "n_keep", params.n_keep },
|
184 |
+
{ "n_left", n_left },
|
185 |
+
{ "new_tokens", tokens_to_str(ctx, new_tokens.cbegin(), new_tokens.cend()) },
|
186 |
+
});
|
187 |
|
188 |
+
truncated = true;
|
189 |
+
prompt_tokens = new_tokens;
|
190 |
+
} else {
|
191 |
+
const size_t ps = prompt_tokens.size();
|
192 |
+
std::fill(last_n_tokens.begin(), last_n_tokens.end() - ps, 0);
|
193 |
+
std::copy(prompt_tokens.begin(), prompt_tokens.end(), last_n_tokens.end() - ps);
|
194 |
}
|
195 |
|
196 |
+
// compare the evaluated prompt with the new prompt
|
197 |
+
n_past = common_part(embd, prompt_tokens);
|
198 |
+
embd = prompt_tokens;
|
199 |
+
if (n_past == prompt_tokens.size()) {
|
200 |
+
// we have to evaluate at least 1 token to generate logits.
|
201 |
+
n_past--;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
202 |
}
|
203 |
|
204 |
+
LOG_VERBOSE("prompt ingested", {
|
205 |
+
{ "n_past", n_past },
|
206 |
+
{ "cached", tokens_to_str(ctx, embd.cbegin(), embd.cbegin() + n_past) },
|
207 |
+
{ "to_eval", tokens_to_str(ctx, embd.cbegin() + n_past, embd.cend()) },
|
208 |
+
});
|
209 |
+
|
210 |
+
has_next_token = true;
|
211 |
+
}
|
212 |
+
|
213 |
+
void beginCompletion() {
|
214 |
+
// number of tokens to keep when resetting context
|
215 |
+
n_remain = params.n_predict;
|
216 |
+
llama_set_rng_seed(ctx, params.seed);
|
217 |
+
}
|
218 |
+
|
219 |
+
llama_token nextToken() {
|
220 |
+
llama_token result = -1;
|
221 |
+
|
222 |
+
if (embd.size() >= (size_t)params.n_ctx) {
|
223 |
+
// Reset context
|
224 |
+
const int n_left = (params.n_ctx - params.n_keep) / 2;
|
225 |
+
|
226 |
+
std::vector<llama_token> new_tokens(embd.begin(), embd.begin() + params.n_keep);
|
227 |
+
new_tokens.insert(new_tokens.end(), embd.end() - n_left, embd.end());
|
228 |
+
embd = new_tokens;
|
229 |
+
n_past = params.n_keep;
|
230 |
+
truncated = true;
|
231 |
+
LOG_VERBOSE("input truncated", {
|
232 |
+
{ "n_ctx", params.n_ctx },
|
233 |
+
{ "n_keep", params.n_keep },
|
234 |
+
{ "n_left", n_left },
|
235 |
+
{ "new_tokens", tokens_to_str(ctx, new_tokens.cbegin(), new_tokens.cend()) },
|
236 |
+
});
|
237 |
}
|
238 |
+
|
239 |
+
while (n_past < embd.size()) {
|
240 |
+
int n_eval = (int)embd.size() - n_past;
|
241 |
+
if (n_eval > params.n_batch) {
|
242 |
+
n_eval = params.n_batch;
|
243 |
+
}
|
244 |
+
if (llama_eval(ctx, &embd[n_past], n_eval, n_past, params.n_threads)) {
|
245 |
+
LOG_ERROR("failed to eval", {
|
246 |
+
{ "n_eval", n_eval },
|
247 |
+
{ "n_past", n_past },
|
248 |
+
{ "n_threads", params.n_threads },
|
249 |
+
{ "embd", tokens_to_str(ctx, embd.cbegin() + n_past, embd.cend()) },
|
250 |
+
});
|
251 |
+
has_next_token = false;
|
252 |
+
return result;
|
253 |
+
}
|
254 |
+
n_past += n_eval;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
255 |
}
|
256 |
+
|
257 |
+
// out of user input, sample next token
|
258 |
+
const float temp = params.temp;
|
259 |
+
const int32_t top_k = params.top_k <= 0 ? llama_n_vocab(ctx) : params.top_k;
|
260 |
+
const float top_p = params.top_p;
|
261 |
+
const float tfs_z = params.tfs_z;
|
262 |
+
const float typical_p = params.typical_p;
|
263 |
+
const int32_t repeat_last_n = params.repeat_last_n < 0 ? params.n_ctx : params.repeat_last_n;
|
264 |
+
const float repeat_penalty = params.repeat_penalty;
|
265 |
+
const float alpha_presence = params.presence_penalty;
|
266 |
+
const float alpha_frequency = params.frequency_penalty;
|
267 |
+
const int mirostat = params.mirostat;
|
268 |
+
const float mirostat_tau = params.mirostat_tau;
|
269 |
+
const float mirostat_eta = params.mirostat_eta;
|
270 |
+
const bool penalize_nl = params.penalize_nl;
|
271 |
+
llama_token id = 0;
|
272 |
+
|
273 |
{
|
274 |
+
auto * logits = llama_get_logits(ctx);
|
275 |
+
auto n_vocab = llama_n_vocab(ctx);
|
276 |
+
|
277 |
+
// Apply params.logit_bias map
|
278 |
+
for (const auto & it : params.logit_bias) {
|
279 |
+
logits[it.first] += it.second;
|
280 |
+
}
|
281 |
+
|
282 |
+
std::vector<llama_token_data> candidates;
|
283 |
+
candidates.reserve(n_vocab);
|
284 |
+
for (llama_token token_id = 0; token_id < n_vocab; token_id++) {
|
285 |
+
candidates.emplace_back(llama_token_data{ token_id, logits[token_id], 0.0f });
|
286 |
+
}
|
287 |
+
|
288 |
+
llama_token_data_array candidates_p = { candidates.data(), candidates.size(), false };
|
289 |
+
|
290 |
+
// Apply penalties
|
291 |
+
float nl_logit = logits[llama_token_nl()];
|
292 |
+
auto last_n_repeat = std::min(std::min((int)last_n_tokens.size(), repeat_last_n), params.n_ctx);
|
293 |
+
llama_sample_repetition_penalty(ctx, &candidates_p,
|
294 |
+
last_n_tokens.data() + last_n_tokens.size() - last_n_repeat,
|
295 |
+
last_n_repeat, repeat_penalty);
|
296 |
+
llama_sample_frequency_and_presence_penalties(ctx, &candidates_p,
|
297 |
+
last_n_tokens.data() + last_n_tokens.size() - last_n_repeat,
|
298 |
+
last_n_repeat, alpha_frequency, alpha_presence);
|
299 |
+
if (!penalize_nl) {
|
300 |
+
logits[llama_token_nl()] = nl_logit;
|
301 |
+
}
|
302 |
+
|
303 |
+
if (temp <= 0) {
|
304 |
+
// Greedy sampling
|
305 |
+
id = llama_sample_token_greedy(ctx, &candidates_p);
|
306 |
+
} else {
|
307 |
+
if (mirostat == 1) {
|
308 |
+
static float mirostat_mu = 2.0f * mirostat_tau;
|
309 |
+
const int mirostat_m = 100;
|
310 |
+
llama_sample_temperature(ctx, &candidates_p, temp);
|
311 |
+
id = llama_sample_token_mirostat(ctx, &candidates_p, mirostat_tau, mirostat_eta, mirostat_m, &mirostat_mu);
|
312 |
+
} else if (mirostat == 2) {
|
313 |
+
static float mirostat_mu = 2.0f * mirostat_tau;
|
314 |
+
llama_sample_temperature(ctx, &candidates_p, temp);
|
315 |
+
id = llama_sample_token_mirostat_v2(ctx, &candidates_p, mirostat_tau, mirostat_eta, &mirostat_mu);
|
316 |
+
} else {
|
317 |
+
// Temperature sampling
|
318 |
+
llama_sample_tail_free(ctx, &candidates_p, tfs_z, 1);
|
319 |
+
llama_sample_typical(ctx, &candidates_p, typical_p, 1);
|
320 |
+
llama_sample_top_p(ctx, &candidates_p, top_p, 1);
|
321 |
+
llama_sample_top_k(ctx, &candidates_p, top_k, 1);
|
322 |
+
llama_sample_temperature(ctx, &candidates_p, temp);
|
323 |
+
id = llama_sample_token(ctx, &candidates_p);
|
324 |
+
}
|
325 |
+
}
|
326 |
+
last_n_tokens.erase(last_n_tokens.begin());
|
327 |
+
last_n_tokens.push_back(id);
|
328 |
+
num_tokens_predicted++;
|
329 |
}
|
|
|
330 |
|
331 |
+
// add it to the context
|
332 |
+
embd.push_back(id);
|
|
|
|
|
333 |
result = id;
|
334 |
+
// decrement remaining sampling budget
|
335 |
+
--n_remain;
|
336 |
+
|
337 |
+
if (!embd.empty() && embd.back() == llama_token_eos()) {
|
338 |
+
//stopping_word = llama_token_to_str(ctx, embd.back());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
339 |
has_next_token = false;
|
340 |
+
stopped_eos = true;
|
341 |
+
LOG_VERBOSE("eos token found", {});
|
342 |
return result;
|
|
|
343 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
344 |
|
345 |
+
has_next_token = params.n_predict == -1 || n_remain != 0;
|
346 |
+
return result;
|
347 |
}
|
348 |
|
349 |
+
size_t findStoppingStrings(const std::string & text, const size_t last_token_size,
|
350 |
+
const stop_type type) {
|
351 |
+
size_t stop_pos = std::string::npos;
|
352 |
+
for (const std::string & word : params.antiprompt) {
|
353 |
+
size_t pos;
|
354 |
+
if (type == STOP_FULL) {
|
355 |
+
const size_t tmp = word.size() + last_token_size;
|
356 |
+
const size_t from_pos = text.size() > tmp ? text.size() - tmp : 0;
|
357 |
+
pos = text.find(word, from_pos);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
358 |
}
|
359 |
+
else {
|
360 |
+
pos = find_partial_stop_string(word, text);
|
|
|
361 |
}
|
362 |
+
if (pos != std::string::npos &&
|
363 |
+
(stop_pos == std::string::npos || pos < stop_pos)) {
|
364 |
+
if (type == STOP_FULL) {
|
365 |
+
stopping_word = word;
|
366 |
+
stopped_word = true;
|
367 |
+
has_next_token = false;
|
368 |
+
}
|
369 |
+
stop_pos = pos;
|
370 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
371 |
}
|
372 |
+
return stop_pos;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
373 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
374 |
|
375 |
+
std::string doCompletion() {
|
376 |
+
const llama_token token = nextToken();
|
377 |
+
|
378 |
+
const std::string token_text = token == -1 ? "" : llama_token_to_str(ctx, token);
|
379 |
+
generated_text += token_text;
|
380 |
+
|
381 |
+
if (multibyte_pending > 0) {
|
382 |
+
multibyte_pending -= token_text.size();
|
383 |
+
} else if (token_text.size() == 1) {
|
384 |
+
const char c = token_text[0];
|
385 |
+
// 2-byte characters: 110xxxxx 10xxxxxx
|
386 |
+
if ((c & 0xE0) == 0xC0) {
|
387 |
+
multibyte_pending = 1;
|
388 |
+
// 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
|
389 |
+
} else if ((c & 0xF0) == 0xE0) {
|
390 |
+
multibyte_pending = 2;
|
391 |
+
// 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
392 |
+
} else if ((c & 0xF8) == 0xF0) {
|
393 |
+
multibyte_pending = 3;
|
394 |
+
} else {
|
395 |
+
multibyte_pending = 0;
|
396 |
+
}
|
397 |
+
}
|
398 |
|
399 |
+
if (multibyte_pending > 0 && !has_next_token) {
|
400 |
+
has_next_token = true;
|
401 |
+
n_remain++;
|
402 |
+
}
|
403 |
|
404 |
+
if (!has_next_token && n_remain == 0) {
|
405 |
+
stopped_limit = true;
|
406 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
407 |
|
408 |
+
LOG_VERBOSE("next token", {
|
409 |
+
{ "token", token },
|
410 |
+
{ "token_text", llama_token_to_str(ctx, token) },
|
411 |
+
{ "has_next_token", has_next_token },
|
412 |
+
{ "n_remain", n_remain },
|
413 |
+
{ "num_tokens_predicted", num_tokens_predicted },
|
414 |
+
{ "stopped_eos", stopped_eos },
|
415 |
+
{ "stopped_word", stopped_word },
|
416 |
+
{ "stopped_limit", stopped_limit },
|
417 |
+
{ "stopping_word", stopping_word },
|
418 |
+
});
|
419 |
+
|
420 |
+
return token_text;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
421 |
}
|
422 |
+
};
|
423 |
+
|
424 |
+
static void server_print_usage(const char * argv0, const gpt_params & params,
|
425 |
+
const server_params & sparams) {
|
426 |
+
fprintf(stderr, "usage: %s [options]\n", argv0);
|
427 |
+
fprintf(stderr, "\n");
|
428 |
+
fprintf(stderr, "options:\n");
|
429 |
+
fprintf(stderr, " -h, --help show this help message and exit\n");
|
430 |
+
fprintf(stderr, " -v, --verbose verbose output (default: %s)\n", server_verbose ? "enabled" : "disabled");
|
431 |
+
fprintf(stderr, " -t N, --threads N number of threads to use during computation (default: %d)\n", params.n_threads);
|
432 |
+
fprintf(stderr, " -c N, --ctx-size N size of the prompt context (default: %d)\n", params.n_ctx);
|
433 |
+
fprintf(stderr, " -b N, --batch-size N batch size for prompt processing (default: %d)\n", params.n_batch);
|
434 |
+
fprintf(stderr, " --memory-f32 use f32 instead of f16 for memory key+value (default: disabled)\n");
|
435 |
+
fprintf(stderr, " not recommended: doubles context memory required and no measurable increase in quality\n");
|
436 |
+
if (llama_mlock_supported()) {
|
437 |
+
fprintf(stderr, " --mlock force system to keep model in RAM rather than swapping or compressing\n");
|
438 |
}
|
439 |
+
if (llama_mmap_supported()) {
|
440 |
+
fprintf(stderr, " --no-mmap do not memory-map model (slower load but may reduce pageouts if not using mlock)\n");
|
|
|
441 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
442 |
#ifdef LLAMA_SUPPORTS_GPU_OFFLOAD
|
443 |
+
fprintf(stderr, " -ngl N, --n-gpu-layers N\n");
|
444 |
+
fprintf(stderr, " number of layers to store in VRAM\n");
|
445 |
+
fprintf(stderr, " -ts SPLIT --tensor-split SPLIT\n");
|
446 |
+
fprintf(stderr, " how to split tensors across multiple GPUs, comma-separated list of proportions, e.g. 3,1\n");
|
447 |
+
fprintf(stderr, " how to split tensors across multiple GPUs, comma-separated list of proportions, e.g. 3,1\n");
|
448 |
+
fprintf(stderr, " -mg i, --main-gpu i the GPU to use for scratch and small tensors\n");
|
449 |
+
fprintf(stderr, " -lv, --low-vram don't allocate VRAM scratch buffer\n");
|
450 |
+
#endif
|
451 |
+
fprintf(stderr, " -m FNAME, --model FNAME\n");
|
452 |
+
fprintf(stderr, " model path (default: %s)\n", params.model.c_str());
|
453 |
+
fprintf(stderr, " -a ALIAS, --alias ALIAS\n");
|
454 |
+
fprintf(stderr, " set an alias for the model, will be added as `model` field in completion response\n");
|
455 |
+
fprintf(stderr, " --lora FNAME apply LoRA adapter (implies --no-mmap)\n");
|
456 |
+
fprintf(stderr, " --lora-base FNAME optional model to use as a base for the layers modified by the LoRA adapter\n");
|
457 |
+
fprintf(stderr, " --host ip address to listen (default (default: %s)\n", sparams.hostname.c_str());
|
458 |
+
fprintf(stderr, " --port PORT port to listen (default (default: %d)\n", sparams.port);
|
459 |
+
fprintf(stderr, " -to N, --timeout N server read/write timeout in seconds (default: %d)\n", sparams.read_timeout);
|
460 |
+
fprintf(stderr, "\n");
|
461 |
+
}
|
462 |
+
|
463 |
+
static void server_params_parse(int argc, char ** argv, server_params & sparams,
|
464 |
+
gpt_params & params) {
|
465 |
+
gpt_params default_params;
|
466 |
+
server_params default_sparams;
|
467 |
+
std::string arg;
|
468 |
+
bool invalid_param = false;
|
469 |
+
|
470 |
+
for (int i = 1; i < argc; i++) {
|
471 |
+
arg = argv[i];
|
472 |
+
if (arg == "--port") {
|
473 |
+
if (++i >= argc) {
|
474 |
+
invalid_param = true;
|
475 |
+
break;
|
476 |
+
}
|
477 |
+
sparams.port = std::stoi(argv[i]);
|
478 |
+
} else if (arg == "--host") {
|
479 |
+
if (++i >= argc) {
|
480 |
+
invalid_param = true;
|
481 |
+
break;
|
482 |
+
}
|
483 |
+
sparams.hostname = argv[i];
|
484 |
+
} else if (arg == "--timeout" || arg == "-to") {
|
485 |
+
if (++i >= argc) {
|
486 |
+
invalid_param = true;
|
487 |
+
break;
|
488 |
+
}
|
489 |
+
sparams.read_timeout = std::stoi(argv[i]);
|
490 |
+
sparams.write_timeout = std::stoi(argv[i]);
|
491 |
+
} else if (arg == "-m" || arg == "--model") {
|
492 |
+
if (++i >= argc) {
|
493 |
+
invalid_param = true;
|
494 |
+
break;
|
495 |
+
}
|
496 |
+
params.model = argv[i];
|
497 |
+
} else if (arg == "-a" || arg == "--alias") {
|
498 |
+
if (++i >= argc) {
|
499 |
+
invalid_param = true;
|
500 |
+
break;
|
501 |
+
}
|
502 |
+
params.model_alias = argv[i];
|
503 |
+
} else if (arg == "-h" || arg == "--help") {
|
504 |
+
server_print_usage(argv[0], default_params, default_sparams);
|
505 |
+
exit(0);
|
506 |
+
} else if (arg == "-c" || arg == "--ctx-size" || arg == "--ctx_size") {
|
507 |
+
if (++i >= argc) {
|
508 |
+
invalid_param = true;
|
509 |
+
break;
|
510 |
+
}
|
511 |
+
params.n_ctx = std::stoi(argv[i]);
|
512 |
+
} else if (arg == "--memory-f32" || arg == "--memory_f32") {
|
513 |
+
params.memory_f16 = false;
|
514 |
+
} else if (arg == "--threads" || arg == "-t") {
|
515 |
+
if (++i >= argc) {
|
516 |
+
invalid_param = true;
|
517 |
+
break;
|
518 |
+
}
|
519 |
+
params.n_threads = std::stoi(argv[i]);
|
520 |
+
} else if (arg == "-b" || arg == "--batch-size") {
|
521 |
+
if (++i >= argc) {
|
522 |
+
invalid_param = true;
|
523 |
+
break;
|
524 |
+
}
|
525 |
+
params.n_batch = std::stoi(argv[i]);
|
526 |
+
params.n_batch = std::min(512, params.n_batch);
|
527 |
+
} else if (arg == "--gpu-layers" || arg == "-ngl" || arg == "--n-gpu-layers") {
|
528 |
+
if (++i >= argc) {
|
529 |
+
invalid_param = true;
|
530 |
+
break;
|
531 |
+
}
|
532 |
+
#ifdef LLAMA_SUPPORTS_GPU_OFFLOAD
|
533 |
+
params.n_gpu_layers = std::stoi(argv[i]);
|
534 |
#else
|
535 |
+
LOG_WARNING("Not compiled with GPU offload support, --n-gpu-layers option will be ignored. "
|
536 |
+
"See main README.md for information on enabling GPU BLAS support", { { "n_gpu_layers", params.n_gpu_layers } });
|
537 |
#endif
|
538 |
+
}
|
539 |
+
else if (arg == "--tensor-split" || arg == "-ts") {
|
540 |
+
if (++i >= argc) {
|
541 |
+
invalid_param = true;
|
542 |
+
break;
|
543 |
+
}
|
|
|
|
|
544 |
#ifdef GGML_USE_CUBLAS
|
545 |
+
std::string arg_next = argv[i];
|
546 |
|
547 |
+
// split string by , and /
|
548 |
+
const std::regex regex{ R"([,/]+)" };
|
549 |
+
std::sregex_token_iterator it{ arg_next.begin(), arg_next.end(), regex, -1 };
|
550 |
+
std::vector<std::string> split_arg{ it, {} };
|
551 |
+
GGML_ASSERT(split_arg.size() <= LLAMA_MAX_DEVICES);
|
552 |
|
553 |
+
for (size_t i_device = 0; i_device < LLAMA_MAX_DEVICES; ++i_device) {
|
554 |
+
if (i_device < split_arg.size()) {
|
555 |
+
params.tensor_split[i_device] = std::stof(split_arg[i_device]);
|
556 |
+
}
|
557 |
+
else {
|
558 |
+
params.tensor_split[i_device] = 0.0f;
|
559 |
+
}
|
560 |
+
}
|
561 |
+
#else
|
562 |
+
LOG_WARNING("llama.cpp was compiled without cuBLAS. It is not possible to set a tensor split.", {});
|
563 |
+
#endif // GGML_USE_CUBLAS
|
564 |
}
|
565 |
+
else if (arg == "--low-vram" || arg == "-lv")
|
566 |
{
|
567 |
+
#ifdef GGML_USE_CUBLAS
|
568 |
+
params.low_vram = true;
|
|
|
569 |
#else
|
570 |
+
fprintf(stderr, "warning: llama.cpp was compiled without cuBLAS. It is not possible to set lower vram usage.\n");
|
571 |
#endif // GGML_USE_CUBLAS
|
572 |
+
}
|
573 |
+
else if (arg == "--main-gpu" || arg == "-mg") {
|
574 |
+
if (++i >= argc) {
|
575 |
+
invalid_param = true;
|
576 |
+
break;
|
577 |
+
}
|
|
|
|
|
578 |
#ifdef GGML_USE_CUBLAS
|
579 |
+
params.main_gpu = std::stoi(argv[i]);
|
580 |
#else
|
581 |
+
LOG_WARNING("llama.cpp was compiled without cuBLAS. It is not possible to set a main GPU.", {});
|
582 |
#endif
|
583 |
+
} else if (arg == "--lora") {
|
584 |
+
if (++i >= argc) {
|
585 |
+
invalid_param = true;
|
586 |
+
break;
|
587 |
+
}
|
588 |
+
params.lora_adapter = argv[i];
|
589 |
+
params.use_mmap = false;
|
590 |
+
} else if (arg == "--lora-base") {
|
591 |
+
if (++i >= argc) {
|
592 |
+
invalid_param = true;
|
593 |
+
break;
|
594 |
+
}
|
595 |
+
params.lora_base = argv[i];
|
596 |
+
} else if (arg == "-v" || arg == "--verbose") {
|
597 |
+
#if SERVER_VERBOSE != 1
|
598 |
+
LOG_WARNING("server.cpp is not built with verbose logging.", {});
|
599 |
+
#else
|
600 |
+
server_verbose = true;
|
601 |
+
#endif
|
602 |
+
} else if (arg == "--mlock") {
|
603 |
+
params.use_mlock = true;
|
604 |
+
} else if (arg == "--no-mmap") {
|
605 |
+
params.use_mmap = false;
|
606 |
+
} else {
|
607 |
+
fprintf(stderr, "error: unknown argument: %s\n", arg.c_str());
|
608 |
+
server_print_usage(argv[0], default_params, default_sparams);
|
609 |
+
exit(1);
|
610 |
+
}
|
611 |
}
|
612 |
+
|
613 |
+
if (invalid_param) {
|
614 |
+
fprintf(stderr, "error: invalid parameter for argument: %s\n", arg.c_str());
|
615 |
+
server_print_usage(argv[0], default_params, default_sparams);
|
616 |
+
exit(1);
|
617 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
618 |
}
|
619 |
|
620 |
+
static json format_generation_settings(llama_server_context & llama) {
|
621 |
+
const auto eos_bias = llama.params.logit_bias.find(llama_token_eos());
|
622 |
+
const bool ignore_eos = eos_bias != llama.params.logit_bias.end() &&
|
623 |
+
eos_bias->second < 0.0f && std::isinf(eos_bias->second);
|
624 |
+
|
625 |
+
return json {
|
626 |
+
{ "seed", llama.params.seed },
|
627 |
+
{ "temp", llama.params.temp },
|
628 |
+
{ "top_k", llama.params.top_k },
|
629 |
+
{ "top_p", llama.params.top_p },
|
630 |
+
{ "tfs_z", llama.params.tfs_z },
|
631 |
+
{ "typical_p", llama.params.typical_p },
|
632 |
+
{ "repeat_last_n", llama.params.repeat_last_n },
|
633 |
+
{ "repeat_penalty", llama.params.repeat_penalty },
|
634 |
+
{ "presence_penalty", llama.params.presence_penalty },
|
635 |
+
{ "frequency_penalty", llama.params.frequency_penalty },
|
636 |
+
{ "mirostat", llama.params.mirostat },
|
637 |
+
{ "mirostat_tau", llama.params.mirostat_tau },
|
638 |
+
{ "mirostat_eta", llama.params.mirostat_eta },
|
639 |
+
{ "penalize_nl", llama.params.penalize_nl },
|
640 |
+
{ "stop", llama.params.antiprompt },
|
641 |
+
{ "n_predict", llama.params.n_predict },
|
642 |
+
{ "n_keep", llama.params.n_keep },
|
643 |
+
{ "ignore_eos", ignore_eos },
|
644 |
+
{ "stream", llama.stream },
|
645 |
+
{ "logit_bias", llama.params.logit_bias },
|
646 |
+
};
|
647 |
+
}
|
648 |
+
|
649 |
+
static json format_final_response(llama_server_context & llama, const std::string & content) {
|
650 |
+
return json {
|
651 |
+
{ "content", content },
|
652 |
+
{ "stop", true },
|
653 |
+
{ "model", llama.params.model_alias },
|
654 |
+
{ "tokens_predicted", llama.num_tokens_predicted },
|
655 |
+
{ "generation_settings", format_generation_settings(llama) },
|
656 |
+
{ "prompt", llama.params.prompt },
|
657 |
+
{ "truncated", llama.truncated },
|
658 |
+
{ "stopped_eos", llama.stopped_eos },
|
659 |
+
{ "stopped_word", llama.stopped_word },
|
660 |
+
{ "stopped_limit", llama.stopped_limit },
|
661 |
+
{ "stopping_word", llama.stopping_word },
|
662 |
+
};
|
663 |
+
}
|
664 |
+
|
665 |
+
static json format_partial_response(const std::string & content) {
|
666 |
+
return json {
|
667 |
+
{ "content", content },
|
668 |
+
{ "stop", false },
|
669 |
+
};
|
670 |
+
}
|
671 |
+
|
672 |
+
static json format_tokenizer_response(const std::vector<llama_token> & tokens) {
|
673 |
+
return json {
|
674 |
+
{ "tokens", tokens }
|
675 |
+
};
|
676 |
+
}
|
677 |
+
|
678 |
+
static void parse_options_completion(const json & body, llama_server_context & llama) {
|
679 |
+
gpt_params default_params;
|
680 |
+
|
681 |
+
llama.stream = body.value("stream", false);
|
682 |
+
llama.params.n_predict = body.value("n_predict", default_params.n_predict);
|
683 |
+
llama.params.top_k = body.value("top_k", default_params.top_k);
|
684 |
+
llama.params.top_p = body.value("top_p", default_params.top_p);
|
685 |
+
llama.params.tfs_z = body.value("tfs_z", default_params.tfs_z);
|
686 |
+
llama.params.typical_p = body.value("typical_p", default_params.typical_p);
|
687 |
+
llama.params.repeat_last_n = body.value("repeat_last_n", default_params.repeat_last_n);
|
688 |
+
llama.params.temp = body.value("temperature", default_params.temp);
|
689 |
+
llama.params.repeat_penalty = body.value("repeat_penalty", default_params.repeat_penalty);
|
690 |
+
llama.params.presence_penalty = body.value("presence_penalty", default_params.presence_penalty);
|
691 |
+
llama.params.frequency_penalty = body.value("frequency_penalty", default_params.frequency_penalty);
|
692 |
+
llama.params.mirostat = body.value("mirostat", default_params.mirostat);
|
693 |
+
llama.params.mirostat_tau = body.value("mirostat_tau", default_params.mirostat_tau);
|
694 |
+
llama.params.mirostat_eta = body.value("mirostat_eta", default_params.mirostat_eta);
|
695 |
+
llama.params.penalize_nl = body.value("penalize_nl", default_params.penalize_nl);
|
696 |
+
llama.params.n_keep = body.value("n_keep", default_params.n_keep);
|
697 |
+
llama.params.seed = body.value("seed", default_params.seed);
|
698 |
+
llama.params.prompt = body.value("prompt", default_params.prompt);
|
699 |
+
|
700 |
+
llama.params.logit_bias.clear();
|
701 |
+
if (body.value("ignore_eos", false)) {
|
702 |
+
llama.params.logit_bias[llama_token_eos()] = -INFINITY;
|
703 |
+
}
|
704 |
+
|
705 |
+
const auto & logit_bias = body.find("logit_bias");
|
706 |
+
if (logit_bias != body.end() && logit_bias->is_array()) {
|
707 |
+
const int n_vocab = llama_n_vocab(llama.ctx);
|
708 |
+
for (const auto & el : *logit_bias) {
|
709 |
+
if (el.is_array() && el.size() == 2 && el[0].is_number_integer()) {
|
710 |
+
llama_token tok = el[0].get<llama_token>();
|
711 |
+
if (tok >= 0 && tok < n_vocab) {
|
712 |
+
if (el[1].is_number()) {
|
713 |
+
llama.params.logit_bias[tok] = el[1].get<float>();
|
714 |
+
} else if (el[1].is_boolean() && !el[1].get<bool>()) {
|
715 |
+
llama.params.logit_bias[tok] = -INFINITY;
|
716 |
+
}
|
717 |
+
}
|
718 |
+
}
|
719 |
+
}
|
720 |
}
|
721 |
+
|
722 |
+
llama.params.antiprompt.clear();
|
723 |
+
const auto & stop = body.find("stop");
|
724 |
+
if (stop != body.end() && stop->is_array()) {
|
725 |
+
for (const auto & word : *stop) {
|
726 |
+
if (!word.empty()) {
|
727 |
+
llama.params.antiprompt.push_back(word);
|
728 |
+
}
|
729 |
+
}
|
730 |
}
|
731 |
+
|
732 |
+
LOG_VERBOSE("completion parameters parsed", format_generation_settings(llama));
|
733 |
}
|
734 |
|
735 |
+
static void log_server_request(const Request & req, const Response & res) {
|
736 |
+
LOG_INFO("request", {
|
737 |
+
{ "remote_addr", req.remote_addr },
|
738 |
+
{ "remote_port", req.remote_port },
|
739 |
+
{ "status", res.status },
|
740 |
+
{ "path", req.path },
|
741 |
+
{ "request", req.body },
|
742 |
+
{ "response", res.body },
|
743 |
+
});
|
744 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
745 |
|
746 |
+
int main(int argc, char ** argv) {
|
747 |
+
// own arguments required by this example
|
748 |
+
gpt_params params;
|
749 |
+
server_params sparams;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
750 |
|
751 |
+
// struct that contains llama context and inference
|
752 |
+
llama_server_context llama;
|
753 |
+
|
754 |
+
server_params_parse(argc, argv, sparams, params);
|
755 |
+
|
756 |
+
if (params.model_alias == "unknown") {
|
757 |
+
params.model_alias = params.model;
|
758 |
+
}
|
759 |
+
|
760 |
+
llama_init_backend();
|
761 |
+
|
762 |
+
LOG_INFO("build info", {
|
763 |
+
{ "build", BUILD_NUMBER },
|
764 |
+
{ "commit", BUILD_COMMIT }
|
765 |
+
});
|
766 |
+
LOG_INFO("system info", {
|
767 |
+
{ "n_threads", params.n_threads },
|
768 |
+
{ "total_threads", std::thread::hardware_concurrency() },
|
769 |
+
{ "system_info", llama_print_system_info() },
|
770 |
+
});
|
771 |
+
|
772 |
+
// load the model
|
773 |
+
if (!llama.loadModel(params)) {
|
774 |
+
return 1;
|
775 |
+
}
|
776 |
+
|
777 |
+
Server svr;
|
778 |
+
|
779 |
+
svr.set_default_headers({
|
780 |
+
{ "Access-Control-Allow-Origin", "*" },
|
781 |
+
{ "Access-Control-Allow-Headers", "content-type" }
|
782 |
+
});
|
783 |
+
|
784 |
+
svr.Get("/", [](const Request &, Response & res) {
|
785 |
+
res.set_content("<h1>llama.cpp server works</h1>", "text/html");
|
786 |
+
});
|
787 |
+
|
788 |
+
svr.Post("/completion", [&llama](const Request & req, Response & res) {
|
789 |
+
llama.rewind();
|
790 |
+
llama_reset_timings(llama.ctx);
|
791 |
+
|
792 |
+
parse_options_completion(json::parse(req.body), llama);
|
793 |
+
|
794 |
+
llama.loadPrompt();
|
795 |
+
llama.beginCompletion();
|
796 |
+
|
797 |
+
if (!llama.stream) {
|
798 |
+
size_t stop_pos = std::string::npos;
|
799 |
+
|
800 |
+
while (llama.has_next_token) {
|
801 |
+
const std::string token_text = llama.doCompletion();
|
802 |
+
|
803 |
+
stop_pos = llama.findStoppingStrings(llama.generated_text,
|
804 |
+
token_text.size(), STOP_FULL);
|
805 |
}
|
806 |
+
|
807 |
+
if (stop_pos == std::string::npos) {
|
808 |
+
stop_pos = llama.findStoppingStrings(llama.generated_text, 0, STOP_PARTIAL);
|
|
|
|
|
809 |
}
|
810 |
+
if (stop_pos != std::string::npos) {
|
811 |
+
llama.generated_text.erase(llama.generated_text.begin() + stop_pos,
|
812 |
+
llama.generated_text.end());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
813 |
}
|
|
|
814 |
|
815 |
+
const json data = format_final_response(llama, llama.generated_text);
|
816 |
+
|
817 |
+
llama_print_timings(llama.ctx);
|
818 |
+
|
819 |
+
res.set_content(data.dump(-1, ' ', false, json::error_handler_t::replace),
|
820 |
+
"application/json");
|
821 |
+
} else {
|
822 |
+
const auto chunked_content_provider = [&](size_t, DataSink & sink) {
|
823 |
+
size_t sent_count = 0;
|
824 |
+
|
825 |
+
while (llama.has_next_token) {
|
826 |
+
const std::string token_text = llama.doCompletion();
|
827 |
+
if (llama.multibyte_pending > 0) {
|
828 |
+
continue;
|
829 |
+
}
|
830 |
+
|
831 |
+
size_t pos = std::min(sent_count, llama.generated_text.size());
|
832 |
+
|
833 |
+
const std::string str_test = llama.generated_text.substr(pos);
|
834 |
+
size_t stop_pos =
|
835 |
+
llama.findStoppingStrings(str_test, token_text.size(), STOP_FULL);
|
836 |
+
if (stop_pos != std::string::npos) {
|
837 |
+
llama.generated_text.erase(
|
838 |
+
llama.generated_text.begin() + pos + stop_pos,
|
839 |
+
llama.generated_text.end());
|
840 |
+
pos = std::min(sent_count, llama.generated_text.size());
|
841 |
+
} else {
|
842 |
+
stop_pos = llama.findStoppingStrings(str_test, token_text.size(),
|
843 |
+
STOP_PARTIAL);
|
844 |
+
}
|
845 |
+
|
846 |
+
const std::string to_send = llama.generated_text.substr(pos, stop_pos);
|
847 |
+
sent_count += to_send.size();
|
848 |
+
|
849 |
+
const json data = llama.has_next_token
|
850 |
+
? format_partial_response(to_send)
|
851 |
+
// Generation is done, send extra information.
|
852 |
+
: format_final_response(llama, to_send);
|
853 |
+
|
854 |
+
const std::string str =
|
855 |
+
"data: " +
|
856 |
+
data.dump(-1, ' ', false, json::error_handler_t::replace) +
|
857 |
+
"\n\n";
|
858 |
+
|
859 |
+
LOG_VERBOSE("data stream", {
|
860 |
+
{ "to_send", str }
|
861 |
+
});
|
862 |
+
|
863 |
+
if (!sink.write(str.data(), str.size())) {
|
864 |
+
LOG_VERBOSE("stream closed", {});
|
865 |
+
llama_print_timings(llama.ctx);
|
866 |
+
return false;
|
867 |
+
}
|
868 |
+
}
|
869 |
|
870 |
+
llama_print_timings(llama.ctx);
|
871 |
+
sink.done();
|
872 |
+
return true;
|
873 |
+
};
|
874 |
+
res.set_chunked_content_provider("text/event-stream", chunked_content_provider);
|
875 |
+
}
|
876 |
+
});
|
877 |
+
|
878 |
+
svr.Options(R"(/.*)", [](const Request &, Response & res) {
|
879 |
+
return res.set_content("", "application/json");
|
880 |
+
});
|
881 |
+
|
882 |
+
svr.Post("/tokenize", [&llama](const Request & req, Response & res) {
|
883 |
+
const json body = json::parse(req.body);
|
884 |
+
const std::string content = body["content"].get<std::string>();
|
885 |
+
const std::vector<llama_token> tokens = llama_tokenize(llama.ctx, content, false);
|
886 |
+
const json data = format_tokenizer_response(tokens);
|
887 |
+
return res.set_content(data.dump(), "application/json");
|
888 |
+
});
|
889 |
+
|
890 |
+
svr.set_logger(log_server_request);
|
891 |
+
|
892 |
+
svr.set_exception_handler([](const Request &, Response & res, std::exception_ptr ep) {
|
893 |
+
const auto * fmt = "500 Internal Server Error\n%s";
|
894 |
+
char buf[BUFSIZ];
|
895 |
+
try {
|
896 |
+
std::rethrow_exception(std::move(ep));
|
897 |
+
} catch (std::exception & e) {
|
898 |
+
snprintf(buf, sizeof(buf), fmt, e.what());
|
899 |
+
} catch (...) {
|
900 |
+
snprintf(buf, sizeof(buf), fmt, "Unknown Exception");
|
901 |
+
}
|
902 |
+
res.set_content(buf, "text/plain");
|
903 |
+
res.status = 500;
|
904 |
+
});
|
905 |
+
|
906 |
+
// set timeouts and change hostname and port
|
907 |
+
svr.set_read_timeout(sparams.read_timeout);
|
908 |
+
svr.set_write_timeout(sparams.write_timeout);
|
909 |
+
|
910 |
+
if (!svr.bind_to_port(sparams.hostname, sparams.port)) {
|
911 |
+
LOG_ERROR("couldn't bind to server socket", {
|
912 |
+
{ "hostname", sparams.hostname },
|
913 |
+
{ "port", sparams.port },
|
914 |
+
});
|
915 |
+
return 1;
|
916 |
+
}
|
917 |
+
|
918 |
+
LOG_INFO("HTTP server listening", {
|
919 |
+
{ "hostname", sparams.hostname },
|
920 |
+
{ "port", sparams.port },
|
921 |
+
});
|
922 |
+
|
923 |
+
if (!svr.listen_after_bind()) {
|
924 |
+
return 1;
|
925 |
+
}
|
926 |
|
927 |
+
return 0;
|
|
|
928 |
}
|
examples/simple/CMakeLists.txt
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
set(TARGET simple)
|
2 |
+
add_executable(${TARGET} simple.cpp)
|
3 |
+
target_link_libraries(${TARGET} PRIVATE common llama ${CMAKE_THREAD_LIBS_INIT})
|
4 |
+
target_compile_features(${TARGET} PRIVATE cxx_std_11)
|
5 |
+
if(TARGET BUILD_INFO)
|
6 |
+
add_dependencies(${TARGET} BUILD_INFO)
|
7 |
+
endif()
|
examples/simple/simple.cpp
ADDED
@@ -0,0 +1,177 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#ifndef _GNU_SOURCE
|
2 |
+
#define _GNU_SOURCE
|
3 |
+
#endif
|
4 |
+
|
5 |
+
#include "common.h"
|
6 |
+
#include "llama.h"
|
7 |
+
#include "build-info.h"
|
8 |
+
|
9 |
+
#include <cassert>
|
10 |
+
#include <cinttypes>
|
11 |
+
#include <cmath>
|
12 |
+
#include <cstdio>
|
13 |
+
#include <cstring>
|
14 |
+
#include <ctime>
|
15 |
+
#include <fstream>
|
16 |
+
#include <iostream>
|
17 |
+
#include <string>
|
18 |
+
#include <vector>
|
19 |
+
|
20 |
+
#if defined (__unix__) || (defined (__APPLE__) && defined (__MACH__))
|
21 |
+
#include <signal.h>
|
22 |
+
#include <unistd.h>
|
23 |
+
#elif defined (_WIN32)
|
24 |
+
#define WIN32_LEAN_AND_MEAN
|
25 |
+
#define NOMINMAX
|
26 |
+
#include <windows.h>
|
27 |
+
#include <signal.h>
|
28 |
+
#endif
|
29 |
+
|
30 |
+
|
31 |
+
|
32 |
+
int main(int argc, char ** argv)
|
33 |
+
{
|
34 |
+
gpt_params params;
|
35 |
+
|
36 |
+
//---------------------------------
|
37 |
+
// Print help :
|
38 |
+
//---------------------------------
|
39 |
+
|
40 |
+
if ( argc == 1 || argv[1][0] == '-' )
|
41 |
+
{
|
42 |
+
printf( "usage: %s MODEL_PATH [PROMPT]\n" , argv[0] );
|
43 |
+
return 1 ;
|
44 |
+
}
|
45 |
+
|
46 |
+
//---------------------------------
|
47 |
+
// Load parameters :
|
48 |
+
//---------------------------------
|
49 |
+
|
50 |
+
if ( argc >= 2 )
|
51 |
+
{
|
52 |
+
params.model = argv[1];
|
53 |
+
}
|
54 |
+
|
55 |
+
if ( argc >= 3 )
|
56 |
+
{
|
57 |
+
params.prompt = argv[2];
|
58 |
+
}
|
59 |
+
|
60 |
+
if ( params.prompt.empty() )
|
61 |
+
{
|
62 |
+
params.prompt = "Hello my name is";
|
63 |
+
}
|
64 |
+
|
65 |
+
//---------------------------------
|
66 |
+
// Init LLM :
|
67 |
+
//---------------------------------
|
68 |
+
|
69 |
+
llama_init_backend();
|
70 |
+
|
71 |
+
llama_context * ctx ;
|
72 |
+
|
73 |
+
ctx = llama_init_from_gpt_params( params );
|
74 |
+
|
75 |
+
if ( ctx == NULL )
|
76 |
+
{
|
77 |
+
fprintf( stderr , "%s: error: unable to load model\n" , __func__ );
|
78 |
+
return 1;
|
79 |
+
}
|
80 |
+
|
81 |
+
//---------------------------------
|
82 |
+
// Tokenize the prompt :
|
83 |
+
//---------------------------------
|
84 |
+
|
85 |
+
std::vector<llama_token> tokens_list;
|
86 |
+
tokens_list = ::llama_tokenize( ctx , params.prompt , true );
|
87 |
+
|
88 |
+
const int max_context_size = llama_n_ctx( ctx );
|
89 |
+
const int max_tokens_list_size = max_context_size - 4 ;
|
90 |
+
|
91 |
+
if ( (int)tokens_list.size() > max_tokens_list_size )
|
92 |
+
{
|
93 |
+
fprintf( stderr , "%s: error: prompt too long (%d tokens, max %d)\n" ,
|
94 |
+
__func__ , (int)tokens_list.size() , max_tokens_list_size );
|
95 |
+
return 1;
|
96 |
+
}
|
97 |
+
|
98 |
+
fprintf( stderr, "\n\n" );
|
99 |
+
|
100 |
+
// Print the tokens from the prompt :
|
101 |
+
|
102 |
+
for( auto id : tokens_list )
|
103 |
+
{
|
104 |
+
printf( "%s" , llama_token_to_str( ctx , id ) );
|
105 |
+
}
|
106 |
+
|
107 |
+
fflush(stdout);
|
108 |
+
|
109 |
+
|
110 |
+
//---------------------------------
|
111 |
+
// Main prediction loop :
|
112 |
+
//---------------------------------
|
113 |
+
|
114 |
+
// The LLM keeps a contextual cache memory of previous token evaluation.
|
115 |
+
// Usually, once this cache is full, it is required to recompute a compressed context based on previous
|
116 |
+
// tokens (see "infinite text generation via context swapping" in the main example), but in this minimalist
|
117 |
+
// example, we will just stop the loop once this cache is full or once an end of stream is detected.
|
118 |
+
|
119 |
+
while ( llama_get_kv_cache_token_count( ctx ) < max_context_size )
|
120 |
+
{
|
121 |
+
//---------------------------------
|
122 |
+
// Evaluate the tokens :
|
123 |
+
//---------------------------------
|
124 |
+
|
125 |
+
if ( llama_eval( ctx , tokens_list.data() , tokens_list.size() , llama_get_kv_cache_token_count( ctx ) , params.n_threads ) )
|
126 |
+
{
|
127 |
+
fprintf( stderr, "%s : failed to eval\n" , __func__ );
|
128 |
+
return 1;
|
129 |
+
}
|
130 |
+
|
131 |
+
tokens_list.clear();
|
132 |
+
|
133 |
+
//---------------------------------
|
134 |
+
// Select the best prediction :
|
135 |
+
//---------------------------------
|
136 |
+
|
137 |
+
llama_token new_token_id = 0;
|
138 |
+
|
139 |
+
auto logits = llama_get_logits( ctx );
|
140 |
+
auto n_vocab = llama_n_vocab( ctx ); // the size of the LLM vocabulary (in tokens)
|
141 |
+
|
142 |
+
std::vector<llama_token_data> candidates;
|
143 |
+
candidates.reserve( n_vocab );
|
144 |
+
|
145 |
+
for( llama_token token_id = 0 ; token_id < n_vocab ; token_id++ )
|
146 |
+
{
|
147 |
+
candidates.emplace_back( llama_token_data{ token_id , logits[ token_id ] , 0.0f } );
|
148 |
+
}
|
149 |
+
|
150 |
+
llama_token_data_array candidates_p = { candidates.data(), candidates.size(), false };
|
151 |
+
|
152 |
+
// Select it using the "Greedy sampling" method :
|
153 |
+
new_token_id = llama_sample_token_greedy( ctx , &candidates_p );
|
154 |
+
|
155 |
+
|
156 |
+
// is it an end of stream ?
|
157 |
+
if ( new_token_id == llama_token_eos() )
|
158 |
+
{
|
159 |
+
fprintf(stderr, " [end of text]\n");
|
160 |
+
break;
|
161 |
+
}
|
162 |
+
|
163 |
+
// Print the new token :
|
164 |
+
printf( "%s" , llama_token_to_str( ctx , new_token_id ) );
|
165 |
+
fflush( stdout );
|
166 |
+
|
167 |
+
// Push this new token for next evaluation :
|
168 |
+
tokens_list.push_back( new_token_id );
|
169 |
+
|
170 |
+
} // wend of main loop
|
171 |
+
|
172 |
+
llama_free( ctx );
|
173 |
+
|
174 |
+
return 0;
|
175 |
+
}
|
176 |
+
|
177 |
+
// EOF
|
examples/train-text-from-scratch/README.md
CHANGED
@@ -4,7 +4,7 @@ Basic usage instructions:
|
|
4 |
|
5 |
```bash
|
6 |
# get training data
|
7 |
-
wget https://
|
8 |
|
9 |
# train
|
10 |
./bin/train-text-from-scratch \
|
|
|
4 |
|
5 |
```bash
|
6 |
# get training data
|
7 |
+
wget https://raw.githubusercontent.com/brunoklein99/deep-learning-notes/master/shakespeare.txt
|
8 |
|
9 |
# train
|
10 |
./bin/train-text-from-scratch \
|
examples/train-text-from-scratch/train-text-from-scratch.cpp
CHANGED
@@ -12,6 +12,9 @@
|
|
12 |
#include <algorithm>
|
13 |
#include <string>
|
14 |
|
|
|
|
|
|
|
15 |
|
16 |
struct random_normal_distribution {
|
17 |
std::mt19937 gen;
|
@@ -20,7 +23,6 @@ struct random_normal_distribution {
|
|
20 |
float max;
|
21 |
};
|
22 |
|
23 |
-
|
24 |
struct random_uniform_distribution {
|
25 |
std::mt19937 gen;
|
26 |
std::uniform_real_distribution<float> rd;
|
@@ -2366,7 +2368,7 @@ void write_tensor(struct llama_file * file, struct ggml_tensor * tensor) {
|
|
2366 |
file->write_u32(0);
|
2367 |
file->write_u32(0);
|
2368 |
file->write_u32(GGML_TYPE_F32);
|
2369 |
-
file->seek(-file->tell() & 31, SEEK_CUR);
|
2370 |
return;
|
2371 |
}
|
2372 |
const char * name = ggml_get_name(tensor);
|
@@ -2381,7 +2383,7 @@ void write_tensor(struct llama_file * file, struct ggml_tensor * tensor) {
|
|
2381 |
file->write_u32(tensor->type);
|
2382 |
file->write_raw(ne, sizeof(ne[0]) * nd);
|
2383 |
file->write_raw(name, name_len);
|
2384 |
-
file->seek(-file->tell() & 31, SEEK_CUR);
|
2385 |
file->write_raw(tensor->data, ggml_nbytes(tensor));
|
2386 |
}
|
2387 |
|
@@ -2402,7 +2404,7 @@ void read_tensor(struct llama_file * file, struct ggml_tensor * tensor) {
|
|
2402 |
std::string name = file->read_string(name_len);
|
2403 |
GGML_ASSERT(strncmp(ggml_get_name(tensor), name.c_str(), sizeof(tensor->name)-1) == 0);
|
2404 |
|
2405 |
-
file->seek(-file->tell() & 31, SEEK_CUR);
|
2406 |
file->read_raw(tensor->data, ggml_nbytes(tensor));
|
2407 |
}
|
2408 |
|
@@ -2756,8 +2758,8 @@ struct train_params get_default_train_params() {
|
|
2756 |
|
2757 |
params.lbfgs_n_iter = 16;
|
2758 |
params.adam_n_iter = 16;
|
2759 |
-
params.adam_alpha = 1e-
|
2760 |
-
params.adam_decay = 1e-
|
2761 |
|
2762 |
params.mem_model_gb = 2;
|
2763 |
params.mem_compute_gb = 24;
|
@@ -3331,8 +3333,8 @@ int main(int argc, char ** argv) {
|
|
3331 |
int n_gen = params.n_predict;
|
3332 |
int sample_ctx = n_tokens - n_tokens/8;
|
3333 |
|
3334 |
-
sampler.params.temp = 0.
|
3335 |
-
sampler.params.repeat_penalty = 1.
|
3336 |
sampler.params.mirostat = 2;
|
3337 |
init_sampler(&sampler, lctx);
|
3338 |
|
|
|
12 |
#include <algorithm>
|
13 |
#include <string>
|
14 |
|
15 |
+
#if defined(_MSC_VER)
|
16 |
+
#pragma warning(disable: 4244 4267) // possible loss of data
|
17 |
+
#endif
|
18 |
|
19 |
struct random_normal_distribution {
|
20 |
std::mt19937 gen;
|
|
|
23 |
float max;
|
24 |
};
|
25 |
|
|
|
26 |
struct random_uniform_distribution {
|
27 |
std::mt19937 gen;
|
28 |
std::uniform_real_distribution<float> rd;
|
|
|
2368 |
file->write_u32(0);
|
2369 |
file->write_u32(0);
|
2370 |
file->write_u32(GGML_TYPE_F32);
|
2371 |
+
file->seek(0-file->tell() & 31, SEEK_CUR);
|
2372 |
return;
|
2373 |
}
|
2374 |
const char * name = ggml_get_name(tensor);
|
|
|
2383 |
file->write_u32(tensor->type);
|
2384 |
file->write_raw(ne, sizeof(ne[0]) * nd);
|
2385 |
file->write_raw(name, name_len);
|
2386 |
+
file->seek(0-file->tell() & 31, SEEK_CUR);
|
2387 |
file->write_raw(tensor->data, ggml_nbytes(tensor));
|
2388 |
}
|
2389 |
|
|
|
2404 |
std::string name = file->read_string(name_len);
|
2405 |
GGML_ASSERT(strncmp(ggml_get_name(tensor), name.c_str(), sizeof(tensor->name)-1) == 0);
|
2406 |
|
2407 |
+
file->seek(0-file->tell() & 31, SEEK_CUR);
|
2408 |
file->read_raw(tensor->data, ggml_nbytes(tensor));
|
2409 |
}
|
2410 |
|
|
|
2758 |
|
2759 |
params.lbfgs_n_iter = 16;
|
2760 |
params.adam_n_iter = 16;
|
2761 |
+
params.adam_alpha = 1e-3f;
|
2762 |
+
params.adam_decay = 1e-3f;
|
2763 |
|
2764 |
params.mem_model_gb = 2;
|
2765 |
params.mem_compute_gb = 24;
|
|
|
3333 |
int n_gen = params.n_predict;
|
3334 |
int sample_ctx = n_tokens - n_tokens/8;
|
3335 |
|
3336 |
+
sampler.params.temp = 0.2f;
|
3337 |
+
sampler.params.repeat_penalty = 1.1f;
|
3338 |
sampler.params.mirostat = 2;
|
3339 |
init_sampler(&sampler, lctx);
|
3340 |
|
ggml-cuda.cu
CHANGED
@@ -1,5 +1,6 @@
|
|
1 |
#include <cstddef>
|
2 |
#include <cstdint>
|
|
|
3 |
#include <stdint.h>
|
4 |
#include <stdio.h>
|
5 |
#include <atomic>
|
@@ -24,7 +25,7 @@ static_assert(sizeof(half) == sizeof(ggml_fp16_t), "wrong fp16 size");
|
|
24 |
} \
|
25 |
} while (0)
|
26 |
|
27 |
-
#if CUDART_VERSION >=
|
28 |
#define CUBLAS_CHECK(err) \
|
29 |
do { \
|
30 |
cublasStatus_t err_ = (err); \
|
@@ -48,6 +49,7 @@ static_assert(sizeof(half) == sizeof(ggml_fp16_t), "wrong fp16 size");
|
|
48 |
typedef void (*dequantize_kernel_t)(const void * vx, const int ib, const int iqs, float & v0, float & v1);
|
49 |
typedef void (*to_fp32_cuda_t)(const void * x, float * y, int k, cudaStream_t stream);
|
50 |
typedef void (*dot_kernel_k_t)(const void * vx, const int ib, const int iqs, const float * y, float & v);
|
|
|
51 |
typedef void (*ggml_cuda_func_t)(const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst);
|
52 |
typedef void (*ggml_cuda_op_t)(
|
53 |
const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst, char * src0_ddq_i, float * src0_ddf_i,
|
@@ -151,7 +153,10 @@ static_assert(sizeof(block_q6_K) == sizeof(ggml_fp16_t) + 13*QK_K/16, "wrong q6_
|
|
151 |
#define CUDA_ADD_BLOCK_SIZE 256
|
152 |
#define CUDA_MUL_BLOCK_SIZE 256
|
153 |
#define CUDA_SILU_BLOCK_SIZE 256
|
|
|
|
|
154 |
#define CUDA_ROPE_BLOCK_SIZE 256
|
|
|
155 |
#define CUDA_DEQUANTIZE_BLOCK_SIZE 256
|
156 |
|
157 |
// dmmv = dequantize_mul_mat_vec
|
@@ -162,6 +167,12 @@ static_assert(sizeof(block_q6_K) == sizeof(ggml_fp16_t) + 13*QK_K/16, "wrong q6_
|
|
162 |
#define GGML_CUDA_DMMV_Y 1
|
163 |
#endif
|
164 |
|
|
|
|
|
|
|
|
|
|
|
|
|
165 |
static __global__ void add_f32(const float * x, const float * y, float * dst, const int k) {
|
166 |
const int i = blockDim.x*blockIdx.x + threadIdx.x;
|
167 |
|
@@ -321,37 +332,6 @@ static __global__ void dequantize_block_q2_K(const void * vx, float * yy) {
|
|
321 |
|
322 |
}
|
323 |
|
324 |
-
static __device__ void vec_dot_q2_K(const void * vx, const int ib, const int iqs, const float * yy, float & result) {
|
325 |
-
|
326 |
-
const block_q2_K * x = (const block_q2_K *) vx;
|
327 |
-
|
328 |
-
// if n is 0, we want to do the lower 128, else the upper 128,
|
329 |
-
// covering y[l+0], y[l+32], y[l+64], y[l+96] and
|
330 |
-
// y[l+16], y[l+48], y[l+80], y[l+112]
|
331 |
-
int n = iqs/128; // 0 or 1
|
332 |
-
int r = iqs - 128*n; // 0...120 in steps of 8
|
333 |
-
int l = r/8; // 0...15 in steps of 1
|
334 |
-
|
335 |
-
const float * y = yy + 128*n + l;
|
336 |
-
const uint8_t * q = x[ib].qs + 32*n + l;
|
337 |
-
const uint8_t * s = x[ib].scales + 8*n;
|
338 |
-
|
339 |
-
const float dall = x[ib].d;
|
340 |
-
const float dmin = x[ib].dmin;
|
341 |
-
|
342 |
-
float sum = y[ 0] * (dall * ((s[0] & 0xF) * ((q[ 0] >> 0) & 3)) - dmin * (s[0] >> 4))
|
343 |
-
+ y[ 32] * (dall * ((s[2] & 0xF) * ((q[ 0] >> 2) & 3)) - dmin * (s[2] >> 4))
|
344 |
-
+ y[ 64] * (dall * ((s[4] & 0xF) * ((q[ 0] >> 4) & 3)) - dmin * (s[4] >> 4))
|
345 |
-
+ y[ 96] * (dall * ((s[6] & 0xF) * ((q[ 0] >> 6) & 3)) - dmin * (s[6] >> 4))
|
346 |
-
+ y[ 16] * (dall * ((s[1] & 0xF) * ((q[16] >> 0) & 3)) - dmin * (s[1] >> 4))
|
347 |
-
+ y[ 48] * (dall * ((s[3] & 0xF) * ((q[16] >> 2) & 3)) - dmin * (s[3] >> 4))
|
348 |
-
+ y[ 80] * (dall * ((s[5] & 0xF) * ((q[16] >> 4) & 3)) - dmin * (s[5] >> 4))
|
349 |
-
+ y[112] * (dall * ((s[7] & 0xF) * ((q[16] >> 6) & 3)) - dmin * (s[7] >> 4));
|
350 |
-
|
351 |
-
result = sum;
|
352 |
-
|
353 |
-
}
|
354 |
-
|
355 |
static __global__ void dequantize_block_q3_K(const void * vx, float * yy) {
|
356 |
|
357 |
int r = threadIdx.x/4;
|
@@ -383,51 +363,6 @@ static __global__ void dequantize_block_q3_K(const void * vx, float * yy) {
|
|
383 |
|
384 |
}
|
385 |
|
386 |
-
static __device__ void vec_dot_q3_K(const void * vx, const int ib, const int iqs, const float * yy, float & result) {
|
387 |
-
|
388 |
-
const block_q3_K * x = (const block_q3_K *) vx;
|
389 |
-
|
390 |
-
const uint32_t kmask1 = 0x03030303;
|
391 |
-
const uint32_t kmask2 = 0x0f0f0f0f;
|
392 |
-
|
393 |
-
uint32_t aux[3];
|
394 |
-
uint32_t utmp[4];
|
395 |
-
|
396 |
-
// if n is 0, we want to do the lower 128, else the upper 128,
|
397 |
-
// covering y[l+0], y[l+32], y[l+64], y[l+96] and
|
398 |
-
// y[l+16], y[l+48], y[l+80], y[l+112]
|
399 |
-
int n = iqs/128; // 0 or 1
|
400 |
-
int r = iqs - 128*n; // 0...120 in steps of 8
|
401 |
-
int l = r/8; // 0...15 in steps of 1
|
402 |
-
|
403 |
-
const float * y = yy + 128*n + l;
|
404 |
-
const uint8_t * q = x[ib].qs + 32*n + l;
|
405 |
-
const uint8_t * hm = x[ib].hmask + l;
|
406 |
-
const int8_t * s = (const int8_t *)utmp + 8*n;
|
407 |
-
|
408 |
-
memcpy(aux, x[ib].scales, 12);
|
409 |
-
utmp[3] = ((aux[1] >> 4) & kmask2) | (((aux[2] >> 6) & kmask1) << 4);
|
410 |
-
utmp[2] = ((aux[0] >> 4) & kmask2) | (((aux[2] >> 4) & kmask1) << 4);
|
411 |
-
utmp[1] = (aux[1] & kmask2) | (((aux[2] >> 2) & kmask1) << 4);
|
412 |
-
utmp[0] = (aux[0] & kmask2) | (((aux[2] >> 0) & kmask1) << 4);
|
413 |
-
|
414 |
-
const float dall = x[ib].d;
|
415 |
-
|
416 |
-
const uint8_t m = 1 << (4*n);
|
417 |
-
|
418 |
-
float sum = y[ 0] * (s[0] - 32) * (((q[ 0] >> 0) & 3) - (hm[ 0] & (m << 0) ? 0 : 4))
|
419 |
-
+ y[ 32] * (s[2] - 32) * (((q[ 0] >> 2) & 3) - (hm[ 0] & (m << 1) ? 0 : 4))
|
420 |
-
+ y[ 64] * (s[4] - 32) * (((q[ 0] >> 4) & 3) - (hm[ 0] & (m << 2) ? 0 : 4))
|
421 |
-
+ y[ 96] * (s[6] - 32) * (((q[ 0] >> 6) & 3) - (hm[ 0] & (m << 3) ? 0 : 4))
|
422 |
-
+ y[ 16] * (s[1] - 32) * (((q[16] >> 0) & 3) - (hm[16] & (m << 0) ? 0 : 4))
|
423 |
-
+ y[ 48] * (s[3] - 32) * (((q[16] >> 2) & 3) - (hm[16] & (m << 1) ? 0 : 4))
|
424 |
-
+ y[ 80] * (s[5] - 32) * (((q[16] >> 4) & 3) - (hm[16] & (m << 2) ? 0 : 4))
|
425 |
-
+ y[112] * (s[7] - 32) * (((q[16] >> 6) & 3) - (hm[16] & (m << 3) ? 0 : 4));
|
426 |
-
|
427 |
-
result = sum * dall;
|
428 |
-
|
429 |
-
}
|
430 |
-
|
431 |
static inline __device__ void get_scale_min_k4(int j, const uint8_t * q, uint8_t & d, uint8_t & m) {
|
432 |
if (j < 4) {
|
433 |
d = q[j] & 63; m = q[j + 4] & 63;
|
@@ -474,38 +409,6 @@ static __global__ void dequantize_block_q4_K(const void * vx, float * yy) {
|
|
474 |
}
|
475 |
}
|
476 |
|
477 |
-
static __device__ void vec_dot_q4_K(const void * vx, const int ib, const int iqs, const float * yy, float & result) {
|
478 |
-
|
479 |
-
const block_q4_K * x = (const block_q4_K *) vx;
|
480 |
-
|
481 |
-
// iqs is in 0...248 in steps of 8 =>
|
482 |
-
const int j = iqs / 64; // j is in 0...3
|
483 |
-
const int ir = (iqs - 64*j)/2; // ir is in 0...28 in steps of 4
|
484 |
-
const int is = 2*j; // is is in 0...6 in steps of 2
|
485 |
-
|
486 |
-
const float * y = yy + 64*j + ir;
|
487 |
-
const uint8_t * q = x[ib].qs + 32*j + ir;
|
488 |
-
|
489 |
-
const float dall = x[ib].d;
|
490 |
-
const float dmin = x[ib].dmin;
|
491 |
-
|
492 |
-
uint8_t sc, m;
|
493 |
-
get_scale_min_k4(is + 0, x[ib].scales, sc, m);
|
494 |
-
const float d1 = dall * sc;
|
495 |
-
const float m1 = dmin * m;
|
496 |
-
get_scale_min_k4(is + 1, x[ib].scales, sc, m);
|
497 |
-
const float d2 = dall * sc;
|
498 |
-
const float m2 = dmin * m;
|
499 |
-
|
500 |
-
float sum = 0;
|
501 |
-
for (int k = 0; k < 4; ++k) {
|
502 |
-
sum += y[k + 0] * (d1 * (q[k] & 0xF) - m1);
|
503 |
-
sum += y[k + 32] * (d2 * (q[k] >> 4) - m2);
|
504 |
-
}
|
505 |
-
result = sum;
|
506 |
-
|
507 |
-
}
|
508 |
-
|
509 |
static __global__ void dequantize_block_q5_K(const void * vx, float * yy) {
|
510 |
const block_q5_K * x = (const block_q5_K *) vx;
|
511 |
|
@@ -539,43 +442,6 @@ static __global__ void dequantize_block_q5_K(const void * vx, float * yy) {
|
|
539 |
y[33] = d2 * ((ql[ 1] >> 4) + (qh[ 1] & hm ? 16 : 0)) - m2;
|
540 |
}
|
541 |
|
542 |
-
static __device__ void vec_dot_q5_K(const void * vx, const int ib, const int iqs, const float * yy, float & result) {
|
543 |
-
|
544 |
-
const block_q5_K * x = (const block_q5_K *) vx;
|
545 |
-
|
546 |
-
// iqs is in 0...248 in steps of 8 =>
|
547 |
-
const int j = iqs / 64; // j is in 0...3
|
548 |
-
const int ir = (iqs - 64*j)/2; // ir is in 0...28 in steps of 4
|
549 |
-
const int is = 2*j; // is is in 0...6 in steps of 2
|
550 |
-
|
551 |
-
const float * y = yy + 64*j + ir;
|
552 |
-
const uint8_t * ql = x[ib].qs + 32*j + ir;
|
553 |
-
const uint8_t * qh = x[ib].qh + ir;
|
554 |
-
|
555 |
-
const float dall = x[ib].d;
|
556 |
-
const float dmin = x[ib].dmin;
|
557 |
-
|
558 |
-
uint8_t sc, m;
|
559 |
-
get_scale_min_k4(is + 0, x[ib].scales, sc, m);
|
560 |
-
const float d1 = dall * sc;
|
561 |
-
const float m1 = dmin * m;
|
562 |
-
get_scale_min_k4(is + 1, x[ib].scales, sc, m);
|
563 |
-
const float d2 = dall * sc;
|
564 |
-
const float m2 = dmin * m;
|
565 |
-
|
566 |
-
uint8_t hm = 1 << is;
|
567 |
-
float sum = 0;
|
568 |
-
for (int k = 0; k < 4; ++k) {
|
569 |
-
sum += y[k + 0] * (d1 * ((ql[k] & 0xF) + (qh[k] & hm ? 16 : 0)) - m1);
|
570 |
-
}
|
571 |
-
hm <<= 1;
|
572 |
-
for (int k = 0; k < 4; ++k) {
|
573 |
-
sum += y[k + 32] * (d2 * ((ql[k] >> 4) + (qh[k] & hm ? 16 : 0)) - m2);
|
574 |
-
}
|
575 |
-
result = sum;
|
576 |
-
|
577 |
-
}
|
578 |
-
|
579 |
static __global__ void dequantize_block_q6_K(const void * vx, float * yy) {
|
580 |
const block_q6_K * x = (const block_q6_K *) vx;
|
581 |
|
@@ -601,31 +467,376 @@ static __global__ void dequantize_block_q6_K(const void * vx, float * yy) {
|
|
601 |
y[96] = d * sc[6] * ((int8_t)((ql[32] >> 4) | (((qh >> 6) & 3) << 4)) - 32);
|
602 |
}
|
603 |
|
604 |
-
static
|
605 |
|
606 |
-
|
607 |
|
608 |
-
const int
|
609 |
-
|
610 |
-
const int is = 8*ip;
|
611 |
|
612 |
-
const
|
|
|
613 |
|
614 |
-
const
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
615 |
|
616 |
-
|
617 |
-
const uint8_t * qh = x[ib].qh + 32*ip + il;
|
618 |
-
const int8_t * sc = x[ib].scales + is;
|
619 |
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
+ y[ 80] * d * sc[5] * ((int8_t)((ql[16] >> 4) | (((qh[16] >> 4) & 3) << 4)) - 32)
|
627 |
-
+ y[112] * d * sc[7] * ((int8_t)((ql[48] >> 4) | (((qh[16] >> 6) & 3) << 4)) - 32);
|
628 |
|
|
|
|
|
|
|
629 |
}
|
630 |
|
631 |
static __device__ void convert_f16(const void * vx, const int ib, const int iqs, float & v0, float & v1){
|
@@ -655,10 +866,15 @@ static __global__ void dequantize_block(const void * vx, float * y, const int k)
|
|
655 |
}
|
656 |
|
657 |
template <int qk, int qr, dequantize_kernel_t dequantize_kernel>
|
658 |
-
static __global__ void dequantize_mul_mat_vec(const void * vx, const float * y, float * dst, const int ncols) {
|
659 |
// qk = quantized weights per x block
|
660 |
// qr = number of quantized weights per data value in x block
|
661 |
-
const int row = blockIdx.
|
|
|
|
|
|
|
|
|
|
|
662 |
const int tid = threadIdx.x;
|
663 |
|
664 |
const int iter_stride = 2*GGML_CUDA_DMMV_X;
|
@@ -702,27 +918,85 @@ static __global__ void dequantize_mul_mat_vec(const void * vx, const float * y,
|
|
702 |
}
|
703 |
}
|
704 |
|
705 |
-
|
706 |
-
|
707 |
-
const int row = blockIdx.x*blockDim.y + threadIdx.y;
|
708 |
-
const int tid = threadIdx.x;
|
709 |
|
710 |
-
const int
|
711 |
-
const int
|
712 |
-
const int num_blocks_per_row = ncols / QK_K;
|
713 |
-
const int ib0 = row*num_blocks_per_row;
|
714 |
|
715 |
-
|
|
|
|
|
716 |
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
const int
|
721 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
722 |
|
723 |
-
|
724 |
-
|
725 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
726 |
}
|
727 |
|
728 |
// sum up partial sums and write back result
|
@@ -732,11 +1006,51 @@ static __global__ void dequantize_mul_mat_vec_k(const void * vx, const float * y
|
|
732 |
tmp += __shfl_xor_sync(0xffffffff, tmp, mask, 32);
|
733 |
}
|
734 |
|
735 |
-
if (
|
736 |
-
dst[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
737 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
738 |
}
|
739 |
|
|
|
740 |
static __global__ void rope_f32(const float * x, float * dst, const int ncols, const float p, const float theta_scale) {
|
741 |
const int col = 2*(blockDim.x*blockIdx.x + threadIdx.x);
|
742 |
|
@@ -758,6 +1072,72 @@ static __global__ void rope_f32(const float * x, float * dst, const int ncols, c
|
|
758 |
dst[i + 1] = x0*sin_theta + x1*cos_theta;
|
759 |
}
|
760 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
761 |
static void add_f32_cuda(const float * x, const float * y, float * dst, const int k, cudaStream_t stream) {
|
762 |
const int num_blocks = (k + CUDA_ADD_BLOCK_SIZE - 1) / CUDA_ADD_BLOCK_SIZE;
|
763 |
add_f32<<<num_blocks, CUDA_ADD_BLOCK_SIZE, 0, stream>>>(x, y, dst, k);
|
@@ -831,73 +1211,83 @@ static void dequantize_row_q6_K_cuda(const void * vx, float * y, const int k, cu
|
|
831 |
|
832 |
static void dequantize_mul_mat_vec_q4_0_cuda(const void * vx, const float * y, float * dst, const int ncols, const int nrows, cudaStream_t stream) {
|
833 |
GGML_ASSERT(ncols % GGML_CUDA_DMMV_X == 0);
|
834 |
-
|
|
|
835 |
const dim3 block_dims(WARP_SIZE, GGML_CUDA_DMMV_Y, 1);
|
836 |
dequantize_mul_mat_vec<QK4_0, QR4_0, dequantize_q4_0>
|
837 |
-
<<<
|
838 |
}
|
839 |
|
840 |
static void dequantize_mul_mat_vec_q4_1_cuda(const void * vx, const float * y, float * dst, const int ncols, const int nrows, cudaStream_t stream) {
|
841 |
GGML_ASSERT(ncols % GGML_CUDA_DMMV_X == 0);
|
842 |
-
|
|
|
843 |
const dim3 block_dims(WARP_SIZE, GGML_CUDA_DMMV_Y, 1);
|
844 |
dequantize_mul_mat_vec<QK4_1, QR4_1, dequantize_q4_1>
|
845 |
-
<<<
|
846 |
}
|
847 |
|
848 |
static void dequantize_mul_mat_vec_q5_0_cuda(const void * vx, const float * y, float * dst, const int ncols, const int nrows, cudaStream_t stream) {
|
849 |
GGML_ASSERT(ncols % GGML_CUDA_DMMV_X == 0);
|
850 |
-
|
|
|
851 |
const dim3 block_dims(WARP_SIZE, GGML_CUDA_DMMV_Y, 1);
|
852 |
dequantize_mul_mat_vec<QK5_0, QR5_0, dequantize_q5_0>
|
853 |
-
<<<
|
854 |
}
|
855 |
|
856 |
static void dequantize_mul_mat_vec_q5_1_cuda(const void * vx, const float * y, float * dst, const int ncols, const int nrows, cudaStream_t stream) {
|
857 |
GGML_ASSERT(ncols % GGML_CUDA_DMMV_X == 0);
|
858 |
-
|
|
|
859 |
const dim3 block_dims(WARP_SIZE, GGML_CUDA_DMMV_Y, 1);
|
860 |
dequantize_mul_mat_vec<QK5_1, QR5_1, dequantize_q5_1>
|
861 |
-
<<<
|
862 |
}
|
863 |
|
864 |
static void dequantize_mul_mat_vec_q8_0_cuda(const void * vx, const float * y, float * dst, const int ncols, const int nrows, cudaStream_t stream) {
|
865 |
GGML_ASSERT(ncols % GGML_CUDA_DMMV_X == 0);
|
866 |
-
|
|
|
867 |
const dim3 block_dims(WARP_SIZE, GGML_CUDA_DMMV_Y, 1);
|
868 |
dequantize_mul_mat_vec<QK8_0, QR8_0, dequantize_q8_0>
|
869 |
-
<<<
|
870 |
}
|
871 |
|
872 |
static void dequantize_mul_mat_vec_q2_K_cuda(const void * vx, const float * y, float * dst, const int ncols, const int nrows, cudaStream_t stream) {
|
873 |
GGML_ASSERT(ncols % QK_K == 0);
|
874 |
const int ny = 2;
|
|
|
|
|
875 |
const dim3 block_dims(32, ny, 1);
|
876 |
-
|
877 |
}
|
878 |
|
879 |
static void dequantize_mul_mat_vec_q3_K_cuda(const void * vx, const float * y, float * dst, const int ncols, const int nrows, cudaStream_t stream) {
|
880 |
GGML_ASSERT(ncols % QK_K == 0);
|
881 |
-
const dim3 block_dims(32,
|
882 |
-
|
883 |
}
|
884 |
|
885 |
static void dequantize_mul_mat_vec_q4_K_cuda(const void * vx, const float * y, float * dst, const int ncols, const int nrows, cudaStream_t stream) {
|
886 |
GGML_ASSERT(ncols % QK_K == 0);
|
887 |
-
const dim3 block_dims(32,
|
888 |
-
|
889 |
}
|
890 |
|
891 |
static void dequantize_mul_mat_vec_q5_K_cuda(const void * vx, const float * y, float * dst, const int ncols, const int nrows, cudaStream_t stream) {
|
892 |
GGML_ASSERT(ncols % QK_K == 0);
|
893 |
-
const dim3 block_dims(32,
|
894 |
-
|
895 |
}
|
896 |
|
897 |
static void dequantize_mul_mat_vec_q6_K_cuda(const void * vx, const float * y, float * dst, const int ncols, const int nrows, cudaStream_t stream) {
|
898 |
GGML_ASSERT(ncols % QK_K == 0);
|
899 |
-
const
|
900 |
-
|
|
|
|
|
|
|
901 |
}
|
902 |
|
903 |
static void convert_fp16_to_fp32_cuda(const void * vx, float * y, const int k, cudaStream_t stream) {
|
@@ -907,10 +1297,11 @@ static void convert_fp16_to_fp32_cuda(const void * vx, float * y, const int k, c
|
|
907 |
|
908 |
static void convert_mul_mat_vec_f16_cuda(const void * vx, const float * y, float * dst, const int ncols, const int nrows, cudaStream_t stream) {
|
909 |
GGML_ASSERT(ncols % GGML_CUDA_DMMV_X == 0);
|
910 |
-
|
|
|
911 |
const dim3 block_dims(WARP_SIZE, GGML_CUDA_DMMV_Y, 1);
|
912 |
dequantize_mul_mat_vec<1, 1, convert_f16>
|
913 |
-
<<<
|
914 |
}
|
915 |
|
916 |
static to_fp32_cuda_t ggml_get_to_fp32_cuda(ggml_type type) {
|
@@ -942,6 +1333,47 @@ static to_fp32_cuda_t ggml_get_to_fp32_cuda(ggml_type type) {
|
|
942 |
}
|
943 |
}
|
944 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
945 |
static void rope_f32_cuda(const float * x, float * dst, const int ncols, const int nrows, const float p, const float theta_scale, cudaStream_t stream) {
|
946 |
GGML_ASSERT(nrows % 2 == 0);
|
947 |
const dim3 block_dims(2*CUDA_ROPE_BLOCK_SIZE, 1, 1);
|
@@ -950,6 +1382,19 @@ static void rope_f32_cuda(const float * x, float * dst, const int ncols, const i
|
|
950 |
rope_f32<<<block_nums, block_dims, 0, stream>>>(x, dst, ncols, p, theta_scale);
|
951 |
}
|
952 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
953 |
// buffer pool for cuda
|
954 |
#define MAX_CUDA_BUFFERS 256
|
955 |
|
@@ -1120,10 +1565,25 @@ void ggml_cuda_host_free(void * ptr) {
|
|
1120 |
CUDA_CHECK(cudaFreeHost(ptr));
|
1121 |
}
|
1122 |
|
1123 |
-
static cudaError_t
|
1124 |
void * dst, const struct ggml_tensor * src, int64_t i3, int64_t i2, int64_t i1_low, int64_t i1_high, cudaStream_t stream) {
|
1125 |
|
1126 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1127 |
const int64_t ne0 = src->ne[0];
|
1128 |
const int64_t nb0 = src->nb[0];
|
1129 |
const int64_t nb1 = src->nb[1];
|
@@ -1134,17 +1594,17 @@ static cudaError_t ggml_cuda_h2d_tensor_2d(
|
|
1134 |
const int64_t bs = ggml_blck_size(type);
|
1135 |
int64_t i1_diff = i1_high - i1_low;
|
1136 |
|
1137 |
-
const
|
1138 |
if (nb0 == ts && nb1 == ts*ne0/bs) {
|
1139 |
-
return cudaMemcpyAsync(
|
1140 |
} else if (nb0 == ts) {
|
1141 |
-
return cudaMemcpy2DAsync(
|
1142 |
} else {
|
1143 |
for (int64_t i1 = 0; i1 < i1_diff; i1++) {
|
1144 |
const void * rx = (const void *) ((const char *) x + i1*nb1);
|
1145 |
-
void * rd = (void *) (
|
1146 |
// pretend the row is a matrix with cols=1
|
1147 |
-
cudaError_t r = cudaMemcpy2DAsync(rd, ts/bs, rx, nb0, ts/bs, ne0,
|
1148 |
if (r != cudaSuccess) return r;
|
1149 |
}
|
1150 |
return cudaSuccess;
|
@@ -1380,8 +1840,81 @@ inline void ggml_cuda_op_rope(
|
|
1380 |
(void) i1;
|
1381 |
}
|
1382 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1383 |
static void ggml_cuda_op(const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst,
|
1384 |
-
ggml_cuda_op_t op, bool src0_needs_f32) {
|
1385 |
const int64_t ne00 = src0->ne[0];
|
1386 |
const int64_t ne01 = src0->ne[1];
|
1387 |
const int64_t ne02 = src0->ne[2];
|
@@ -1404,21 +1937,27 @@ static void ggml_cuda_op(const ggml_tensor * src0, const ggml_tensor * src1, ggm
|
|
1404 |
GGML_ASSERT(!use_src1 || src1->backend != GGML_BACKEND_GPU_SPLIT);
|
1405 |
|
1406 |
// strides for iteration over dims 3 and 2
|
1407 |
-
const int64_t
|
1408 |
-
const int64_t
|
1409 |
-
const int64_t
|
1410 |
-
const int64_t
|
|
|
1411 |
|
1412 |
const size_t src0_ts = ggml_type_size(src0->type);
|
1413 |
const size_t src0_bs = ggml_blck_size(src0->type);
|
1414 |
|
1415 |
-
struct ggml_tensor_extra_gpu * src0_extra =
|
1416 |
struct ggml_tensor_extra_gpu * src1_extra = use_src1 ? (ggml_tensor_extra_gpu *) src1->extra : nullptr;
|
1417 |
-
struct ggml_tensor_extra_gpu * dst_extra
|
1418 |
|
1419 |
const bool src0_on_device = src0->backend == GGML_BACKEND_GPU || src0->backend == GGML_BACKEND_GPU_SPLIT;
|
|
|
1420 |
const bool src0_is_f32 = src0->type == GGML_TYPE_F32;
|
1421 |
|
|
|
|
|
|
|
|
|
1422 |
const bool split = src0->backend == GGML_BACKEND_GPU_SPLIT;
|
1423 |
|
1424 |
const to_fp32_cuda_t to_fp32_cuda = ggml_get_to_fp32_cuda(src0->type);
|
@@ -1427,13 +1966,13 @@ static void ggml_cuda_op(const ggml_tensor * src0, const ggml_tensor * src1, ggm
|
|
1427 |
char * src0_ddq[GGML_CUDA_MAX_DEVICES] = {nullptr}; // quantized
|
1428 |
float * src0_ddf[GGML_CUDA_MAX_DEVICES] = {nullptr}; // float
|
1429 |
float * src1_ddf[GGML_CUDA_MAX_DEVICES] = {nullptr};
|
1430 |
-
float *
|
1431 |
|
1432 |
// asq = actual size quantized, asf = actual size float
|
1433 |
size_t src0_asq[GGML_CUDA_MAX_DEVICES] = {0};
|
1434 |
size_t src0_asf[GGML_CUDA_MAX_DEVICES] = {0};
|
1435 |
size_t src1_asf[GGML_CUDA_MAX_DEVICES] = {0};
|
1436 |
-
size_t
|
1437 |
|
1438 |
for (int id = 0; id < g_device_count; ++id) {
|
1439 |
if (!split && id != g_main_device) {
|
@@ -1446,9 +1985,7 @@ static void ggml_cuda_op(const ggml_tensor * src0, const ggml_tensor * src1, ggm
|
|
1446 |
int64_t row_low, row_high;
|
1447 |
if (split) {
|
1448 |
row_low = id == 0 ? 0 : nrows0*g_tensor_split[id];
|
1449 |
-
row_low -= row_low % GGML_CUDA_DMMV_Y;
|
1450 |
row_high = id == g_device_count - 1 ? nrows0 : nrows0*g_tensor_split[id + 1];
|
1451 |
-
row_high -= row_high % GGML_CUDA_DMMV_Y;
|
1452 |
} else {
|
1453 |
row_low = 0;
|
1454 |
row_high = nrows0;
|
@@ -1461,7 +1998,7 @@ static void ggml_cuda_op(const ggml_tensor * src0, const ggml_tensor * src1, ggm
|
|
1461 |
|
1462 |
cudaSetDevice(id);
|
1463 |
|
1464 |
-
if (src0_on_device) {
|
1465 |
if (src0_is_f32) {
|
1466 |
src0_ddf[id] = (float *) src0_extra->data_device[id];
|
1467 |
} else {
|
@@ -1479,8 +2016,8 @@ static void ggml_cuda_op(const ggml_tensor * src0, const ggml_tensor * src1, ggm
|
|
1479 |
src0_ddf[id] = (float *) ggml_cuda_pool_malloc(row_diff*ne00 * sizeof(float), &src0_asf[id]);
|
1480 |
}
|
1481 |
|
1482 |
-
if (use_src1) {
|
1483 |
-
if (src1_on_device) {
|
1484 |
src1_ddf[id] = (float *) src1_extra->data_device[id];
|
1485 |
} else {
|
1486 |
src1_ddf[id] = (float *) ggml_cuda_pool_malloc(num_iters*src1_stride * sizeof(float), &src1_asf[id]);
|
@@ -1493,26 +2030,32 @@ static void ggml_cuda_op(const ggml_tensor * src0, const ggml_tensor * src1, ggm
|
|
1493 |
dst_ddf[id] = (float *) ggml_cuda_pool_malloc(size_dst_ddf, &dst_asf[id]);
|
1494 |
}
|
1495 |
|
1496 |
-
|
|
|
|
|
|
|
|
|
1497 |
const int64_t i13 = i03 % ne13;
|
1498 |
-
for (int64_t i02 = 0; i02 <
|
1499 |
const int64_t i12 = i02 % ne12;
|
1500 |
|
1501 |
const int64_t i0 = i03*ne02 + i02;
|
1502 |
-
|
1503 |
-
|
|
|
|
|
1504 |
|
1505 |
int64_t i01_low = 0;
|
1506 |
-
int64_t i01_high =
|
1507 |
if (split) {
|
1508 |
if (i0 < i0_offset_low || i0 > i0_offset_high) {
|
1509 |
continue;
|
1510 |
}
|
1511 |
if (i0 == i0_offset_low) {
|
1512 |
-
i01_low = row_low %
|
1513 |
}
|
1514 |
if (i0 == i0_offset_high) {
|
1515 |
-
i01_high = row_high %
|
1516 |
}
|
1517 |
}
|
1518 |
|
@@ -1521,7 +2064,7 @@ static void ggml_cuda_op(const ggml_tensor * src0, const ggml_tensor * src1, ggm
|
|
1521 |
// Removing both asserts results in i01_high becoming 0 which in turn results in garbage output.
|
1522 |
// The root cause seems to be a problem with i0_offset_high becoming 0 when it should always be >0 (for single GPU).
|
1523 |
GGML_ASSERT(i01_low == 0 || g_device_count > 1);
|
1524 |
-
GGML_ASSERT(i01_high ==
|
1525 |
|
1526 |
const int64_t i01_diff = i01_high - i01_low;
|
1527 |
if (i01_diff == 0) {
|
@@ -1529,24 +2072,23 @@ static void ggml_cuda_op(const ggml_tensor * src0, const ggml_tensor * src1, ggm
|
|
1529 |
}
|
1530 |
const int64_t i11 = i13*ne12 + i12;
|
1531 |
|
1532 |
-
cudaStream_t cudaStream_main
|
1533 |
cudaStream_t cudaStream_memcpy_src1 = g_cudaStreams_memcpy_src1[id][i0 % GGML_CUDA_MAX_STREAMS];
|
1534 |
-
cudaEvent_t cudaEvent_memcpy_src1
|
1535 |
|
1536 |
// for split tensors the data begins at i0 == i0_offset_low
|
1537 |
char * src0_ddq_i = src0_ddq[id] + (i0 - i0_offset_low)*src0_stride*src0_ts/src0_bs;
|
1538 |
float * src0_ddf_i = src0_ddf[id] + (i0 - i0_offset_low)*src0_stride;
|
1539 |
float * src1_ddf_i = src1_ddf[id] + i11*src1_stride;
|
1540 |
-
float * dst_ddf_i
|
1541 |
|
1542 |
// for split tensors the data pointer needs to be rounded down
|
1543 |
// to the bin edge for i03, i02 bins beyond the first
|
1544 |
if (i0 - i0_offset_low > 0) {
|
|
|
1545 |
src0_ddq_i -= (row_low % ne01)*ne00 * src0_ts/src0_bs;
|
1546 |
src0_ddf_i -= (row_low % ne01)*ne00;
|
1547 |
-
|
1548 |
-
if (i0 - i0_offset_low > 0) {
|
1549 |
-
dst_ddf_i -= (row_low % ne0)*ne1;
|
1550 |
}
|
1551 |
|
1552 |
// the main device memory buffer can be on VRAM scratch, with space for all partial results
|
@@ -1556,30 +2098,37 @@ static void ggml_cuda_op(const ggml_tensor * src0, const ggml_tensor * src1, ggm
|
|
1556 |
}
|
1557 |
|
1558 |
// copy src0, src1 to device if necessary
|
1559 |
-
if (use_src1) {
|
1560 |
if (src1->backend == GGML_BACKEND_CPU) {
|
1561 |
-
|
1562 |
-
|
|
|
|
|
1563 |
if (id != g_main_device) {
|
|
|
1564 |
float * src1_ddf_i_source = (float *) src1_extra->data_device[g_main_device];
|
1565 |
src1_ddf_i_source += i11*src1_stride;
|
1566 |
CUDA_CHECK(cudaMemcpyAsync(src1_ddf_i, src1_ddf_i_source, src1_stride*sizeof(float),
|
1567 |
cudaMemcpyDeviceToDevice, cudaStream_memcpy_src1));
|
1568 |
}
|
|
|
|
|
|
|
1569 |
} else {
|
1570 |
GGML_ASSERT(false);
|
1571 |
}
|
1572 |
}
|
1573 |
CUDA_CHECK(cudaEventRecord(cudaEvent_memcpy_src1, cudaStream_memcpy_src1));
|
1574 |
-
|
|
|
1575 |
if (src0_is_f32) {
|
1576 |
-
CUDA_CHECK(
|
1577 |
} else {
|
1578 |
-
CUDA_CHECK(
|
1579 |
}
|
1580 |
}
|
1581 |
|
1582 |
-
// convert src0 to f32 if it
|
1583 |
if (src0_needs_f32 && !src0_is_f32) {
|
1584 |
to_fp32_cuda(src0_ddq_i, src0_ddf_i, i01_diff*ne00, cudaStream_main);
|
1585 |
CUDA_CHECK(cudaGetLastError());
|
@@ -1644,39 +2193,30 @@ static void ggml_cuda_op(const ggml_tensor * src0, const ggml_tensor * src1, ggm
|
|
1644 |
|
1645 |
void ggml_cuda_add(const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
|
1646 |
GGML_ASSERT(src0->type == GGML_TYPE_F32 && src1->type == GGML_TYPE_F32 && dst->type == GGML_TYPE_F32);
|
1647 |
-
ggml_cuda_op(src0, src1, dst, ggml_cuda_op_add, true);
|
1648 |
}
|
1649 |
|
1650 |
void ggml_cuda_mul(const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
|
1651 |
GGML_ASSERT(src0->type == GGML_TYPE_F32 && src1->type == GGML_TYPE_F32 && dst->type == GGML_TYPE_F32);
|
1652 |
-
ggml_cuda_op(src0, src1, dst, ggml_cuda_op_mul, true);
|
1653 |
}
|
1654 |
|
1655 |
void ggml_cuda_silu(const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
|
1656 |
GGML_ASSERT(src0->type == GGML_TYPE_F32 && dst->type == GGML_TYPE_F32);
|
1657 |
-
ggml_cuda_op(src0, src1, dst, ggml_cuda_op_silu, true);
|
1658 |
}
|
1659 |
|
1660 |
void ggml_cuda_rms_norm(const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
|
1661 |
GGML_ASSERT(src0->type == GGML_TYPE_F32 && dst->type == GGML_TYPE_F32);
|
1662 |
-
ggml_cuda_op(src0, src1, dst, ggml_cuda_op_rms_norm, true);
|
1663 |
}
|
1664 |
|
1665 |
bool ggml_cuda_can_mul_mat(const struct ggml_tensor * src0, const struct ggml_tensor * src1, struct ggml_tensor * dst) {
|
1666 |
-
GGML_ASSERT(src0->backend != GGML_BACKEND_GPU);
|
1667 |
const int64_t ne10 = src1->ne[0];
|
1668 |
|
1669 |
const int64_t ne0 = dst->ne[0];
|
1670 |
const int64_t ne1 = dst->ne[1];
|
1671 |
|
1672 |
-
// if (strcmp(dst->name, "KQ") == 0 || strcmp(dst->name, "KQV") == 0) {
|
1673 |
-
// fprintf(stderr, "(%ld, %ld, %ld, %ld) + (%ld, %ld, %ld, %ld) -> (%ld, %ld, %ld, %ld)\n",
|
1674 |
-
// src0->ne[0], src0->ne[1], src0->ne[2], src0->ne[3],
|
1675 |
-
// src1->ne[0], src1->ne[1], src1->ne[2], src1->ne[3],
|
1676 |
-
// dst->ne[0], dst->ne[1], dst->ne[2], dst->ne[3]);
|
1677 |
-
// return false;
|
1678 |
-
// }
|
1679 |
-
|
1680 |
// TODO: find the optimal values for these
|
1681 |
if ((src0->type == GGML_TYPE_F32 || src0->type == GGML_TYPE_F16 || ggml_is_quantized(src0->type)) &&
|
1682 |
src1->type == GGML_TYPE_F32 &&
|
@@ -1688,23 +2228,158 @@ bool ggml_cuda_can_mul_mat(const struct ggml_tensor * src0, const struct ggml_te
|
|
1688 |
return false;
|
1689 |
}
|
1690 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1691 |
void ggml_cuda_mul_mat(const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
|
1692 |
-
|
1693 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1694 |
} else if (ggml_is_quantized(src0->type) || src0->type == GGML_TYPE_F16) {
|
1695 |
-
if (src1->ne[1] == 1) {
|
1696 |
-
ggml_cuda_op(src0, src1, dst, ggml_cuda_op_dequantize_mul_mat_vec, false);
|
1697 |
} else {
|
1698 |
-
ggml_cuda_op(src0, src1, dst, ggml_cuda_op_mul_mat_cublas, true);
|
1699 |
}
|
1700 |
} else {
|
1701 |
GGML_ASSERT(false);
|
1702 |
}
|
1703 |
}
|
1704 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1705 |
void ggml_cuda_rope(const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
|
1706 |
GGML_ASSERT(src0->type == GGML_TYPE_F32 && dst->type == GGML_TYPE_F32);
|
1707 |
-
ggml_cuda_op(src0, src1, dst, ggml_cuda_op_rope, true);
|
1708 |
}
|
1709 |
|
1710 |
void ggml_cuda_nop(const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
|
@@ -1718,10 +2393,9 @@ void ggml_cuda_transform_tensor(void * data, struct ggml_tensor * tensor) {
|
|
1718 |
const size_t nb1 = tensor->nb[1];
|
1719 |
ggml_backend backend = tensor->backend;
|
1720 |
struct ggml_tensor_extra_gpu * extra = new struct ggml_tensor_extra_gpu;
|
|
|
1721 |
|
1722 |
for (int id = 0; id < g_device_count; ++id) {
|
1723 |
-
extra->data_device[id] = nullptr;
|
1724 |
-
|
1725 |
if (backend == GGML_BACKEND_GPU && id != g_main_device) {
|
1726 |
continue;
|
1727 |
}
|
@@ -1734,10 +2408,7 @@ void ggml_cuda_transform_tensor(void * data, struct ggml_tensor * tensor) {
|
|
1734 |
row_high = nrows;
|
1735 |
} else if (backend == GGML_BACKEND_GPU_SPLIT) {
|
1736 |
row_low = id == 0 ? 0 : nrows*g_tensor_split[id];
|
1737 |
-
row_low -= row_low % GGML_CUDA_DMMV_Y;
|
1738 |
row_high = id == g_device_count - 1 ? nrows : nrows*g_tensor_split[id + 1];
|
1739 |
-
row_high -= row_high % GGML_CUDA_DMMV_Y;
|
1740 |
-
GGML_ASSERT(nrows % GGML_CUDA_DMMV_Y == 0);
|
1741 |
} else {
|
1742 |
GGML_ASSERT(false);
|
1743 |
}
|
@@ -1781,47 +2452,78 @@ void ggml_cuda_free_data(struct ggml_tensor * tensor) {
|
|
1781 |
delete extra;
|
1782 |
}
|
1783 |
|
1784 |
-
void
|
1785 |
-
if (
|
1786 |
-
|
1787 |
}
|
1788 |
|
1789 |
-
|
1790 |
-
|
1791 |
-
|
1792 |
-
|
|
|
|
|
|
|
|
|
|
|
1793 |
}
|
1794 |
|
1795 |
tensor->backend = GGML_BACKEND_GPU;
|
1796 |
struct ggml_tensor_extra_gpu * extra = new ggml_tensor_extra_gpu;
|
1797 |
|
1798 |
-
bool inplace = tensor->src0 != nullptr && tensor->src0->data == tensor->data
|
|
|
|
|
1799 |
|
1800 |
CUDA_CHECK(cudaSetDevice(g_main_device));
|
1801 |
if (inplace && tensor->src0->backend == GGML_BACKEND_GPU) {
|
1802 |
struct ggml_tensor_extra_gpu * src0_extra = (ggml_tensor_extra_gpu * ) tensor->src0->extra;
|
1803 |
-
|
1804 |
-
|
1805 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1806 |
char * data = (char *) g_scratch_buffer;
|
1807 |
if (data == nullptr) {
|
1808 |
CUDA_CHECK(cudaMalloc(&data, g_scratch_size));
|
1809 |
g_scratch_buffer = data;
|
1810 |
}
|
1811 |
extra->data_device[g_main_device] = data + g_scratch_offset;
|
1812 |
-
}
|
1813 |
|
1814 |
-
|
1815 |
-
|
1816 |
-
|
1817 |
-
|
|
|
|
|
|
|
|
|
|
|
1818 |
|
1819 |
-
GGML_ASSERT(g_scratch_offset <= g_scratch_size);
|
1820 |
tensor->extra = extra;
|
1821 |
}
|
1822 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1823 |
void ggml_cuda_set_main_device(int main_device) {
|
1824 |
-
if (main_device
|
1825 |
fprintf(stderr, "warning: cannot set main_device=%d because there are only %d devices. Using device %d instead.\n",
|
1826 |
main_device, g_device_count, g_main_device);
|
1827 |
return;
|
@@ -1838,6 +2540,15 @@ void ggml_cuda_set_scratch_size(size_t scratch_size) {
|
|
1838 |
g_scratch_size = scratch_size;
|
1839 |
}
|
1840 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1841 |
bool ggml_cuda_compute_forward(struct ggml_compute_params * params, struct ggml_tensor * tensor){
|
1842 |
ggml_cuda_func_t func;
|
1843 |
const bool any_on_device = tensor->backend == GGML_BACKEND_GPU
|
@@ -1875,12 +2586,39 @@ bool ggml_cuda_compute_forward(struct ggml_compute_params * params, struct ggml_
|
|
1875 |
}
|
1876 |
func = ggml_cuda_mul_mat;
|
1877 |
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1878 |
case GGML_OP_RESHAPE:
|
|
|
|
|
|
|
1879 |
if (!any_on_device) {
|
1880 |
return false;
|
1881 |
}
|
1882 |
func = ggml_cuda_nop;
|
1883 |
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1884 |
case GGML_OP_ROPE:
|
1885 |
if (!any_on_device) {
|
1886 |
return false;
|
|
|
1 |
#include <cstddef>
|
2 |
#include <cstdint>
|
3 |
+
#include <limits>
|
4 |
#include <stdint.h>
|
5 |
#include <stdio.h>
|
6 |
#include <atomic>
|
|
|
25 |
} \
|
26 |
} while (0)
|
27 |
|
28 |
+
#if CUDART_VERSION >= 12000
|
29 |
#define CUBLAS_CHECK(err) \
|
30 |
do { \
|
31 |
cublasStatus_t err_ = (err); \
|
|
|
49 |
typedef void (*dequantize_kernel_t)(const void * vx, const int ib, const int iqs, float & v0, float & v1);
|
50 |
typedef void (*to_fp32_cuda_t)(const void * x, float * y, int k, cudaStream_t stream);
|
51 |
typedef void (*dot_kernel_k_t)(const void * vx, const int ib, const int iqs, const float * y, float & v);
|
52 |
+
typedef void (*cpy_kernel_t)(const char * cx, char * cdst);
|
53 |
typedef void (*ggml_cuda_func_t)(const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst);
|
54 |
typedef void (*ggml_cuda_op_t)(
|
55 |
const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst, char * src0_ddq_i, float * src0_ddf_i,
|
|
|
153 |
#define CUDA_ADD_BLOCK_SIZE 256
|
154 |
#define CUDA_MUL_BLOCK_SIZE 256
|
155 |
#define CUDA_SILU_BLOCK_SIZE 256
|
156 |
+
#define CUDA_CPY_BLOCK_SIZE 32
|
157 |
+
#define CUDA_SCALE_BLOCK_SIZE 256
|
158 |
#define CUDA_ROPE_BLOCK_SIZE 256
|
159 |
+
#define CUDA_DIAG_MASK_INF_BLOCK_SIZE 32
|
160 |
#define CUDA_DEQUANTIZE_BLOCK_SIZE 256
|
161 |
|
162 |
// dmmv = dequantize_mul_mat_vec
|
|
|
167 |
#define GGML_CUDA_DMMV_Y 1
|
168 |
#endif
|
169 |
|
170 |
+
#ifndef K_QUANTS_PER_ITERATION
|
171 |
+
#define K_QUANTS_PER_ITERATION 2
|
172 |
+
#else
|
173 |
+
static_assert(K_QUANTS_PER_ITERATION == 1 || K_QUANTS_PER_ITERATION == 2, "K_QUANTS_PER_ITERATION must be 1 or 2");
|
174 |
+
#endif
|
175 |
+
|
176 |
static __global__ void add_f32(const float * x, const float * y, float * dst, const int k) {
|
177 |
const int i = blockDim.x*blockIdx.x + threadIdx.x;
|
178 |
|
|
|
332 |
|
333 |
}
|
334 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
335 |
static __global__ void dequantize_block_q3_K(const void * vx, float * yy) {
|
336 |
|
337 |
int r = threadIdx.x/4;
|
|
|
363 |
|
364 |
}
|
365 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
366 |
static inline __device__ void get_scale_min_k4(int j, const uint8_t * q, uint8_t & d, uint8_t & m) {
|
367 |
if (j < 4) {
|
368 |
d = q[j] & 63; m = q[j + 4] & 63;
|
|
|
409 |
}
|
410 |
}
|
411 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
412 |
static __global__ void dequantize_block_q5_K(const void * vx, float * yy) {
|
413 |
const block_q5_K * x = (const block_q5_K *) vx;
|
414 |
|
|
|
442 |
y[33] = d2 * ((ql[ 1] >> 4) + (qh[ 1] & hm ? 16 : 0)) - m2;
|
443 |
}
|
444 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
445 |
static __global__ void dequantize_block_q6_K(const void * vx, float * yy) {
|
446 |
const block_q6_K * x = (const block_q6_K *) vx;
|
447 |
|
|
|
467 |
y[96] = d * sc[6] * ((int8_t)((ql[32] >> 4) | (((qh >> 6) & 3) << 4)) - 32);
|
468 |
}
|
469 |
|
470 |
+
static __global__ void dequantize_mul_mat_vec_q2_k(const void * vx, const float * yy, float * dst, const int ncols, int nrows) {
|
471 |
|
472 |
+
static_assert(16%K_QUANTS_PER_ITERATION == 0, "16 must be divisible by K_QUANTS_PER_ITERATION");
|
473 |
|
474 |
+
const int row = blockIdx.y*blockDim.y + threadIdx.y;
|
475 |
+
if (row > nrows) return;
|
|
|
476 |
|
477 |
+
const int num_blocks_per_row = ncols / QK_K;
|
478 |
+
const int ib0 = row*num_blocks_per_row;
|
479 |
|
480 |
+
const block_q2_K * x = (const block_q2_K *)vx + ib0;
|
481 |
+
|
482 |
+
const int tid = threadIdx.x/K_QUANTS_PER_ITERATION; // 0...31
|
483 |
+
const int ix = threadIdx.x%K_QUANTS_PER_ITERATION; // 0
|
484 |
+
|
485 |
+
const int step = 16/K_QUANTS_PER_ITERATION;
|
486 |
+
|
487 |
+
const int im = tid/step; // 0 or 1. 0 computes 0..., 1 computes 128...
|
488 |
+
const int in = tid - step*im; // 0...7
|
489 |
+
|
490 |
+
const int l0 = K_QUANTS_PER_ITERATION*in; // 0...14 in steps of 4
|
491 |
+
const int q_offset = 32*im + l0;
|
492 |
+
const int s_offset = 8*im;
|
493 |
+
const int y_offset = 128*im + l0;
|
494 |
+
|
495 |
+
float tmp = 0; // partial sum for thread in warp
|
496 |
+
|
497 |
+
uint32_t aux[4];
|
498 |
+
const uint8_t * d = (const uint8_t *)aux;
|
499 |
+
const uint8_t * m = (const uint8_t *)(aux + 2);
|
500 |
+
|
501 |
+
for (int i = ix; i < num_blocks_per_row; i += K_QUANTS_PER_ITERATION) {
|
502 |
+
|
503 |
+
const float * y = yy + i * QK_K + y_offset;
|
504 |
+
const uint8_t * q = x[i].qs + q_offset;
|
505 |
+
|
506 |
+
const float dall = x[i].d;
|
507 |
+
const float dmin = x[i].dmin;
|
508 |
+
|
509 |
+
const uint32_t * a = (const uint32_t *)(x[i].scales + s_offset);
|
510 |
+
aux[0] = a[0] & 0x0f0f0f0f;
|
511 |
+
aux[1] = a[1] & 0x0f0f0f0f;
|
512 |
+
aux[2] = (a[0] >> 4) & 0x0f0f0f0f;
|
513 |
+
aux[3] = (a[1] >> 4) & 0x0f0f0f0f;
|
514 |
+
|
515 |
+
float sum1 = 0, sum2 = 0;
|
516 |
+
for (int l = 0; l < K_QUANTS_PER_ITERATION; ++l) {
|
517 |
+
sum1 += y[l+ 0] * d[0] * ((q[l+ 0] >> 0) & 3)
|
518 |
+
+ y[l+32] * d[2] * ((q[l+ 0] >> 2) & 3)
|
519 |
+
+ y[l+64] * d[4] * ((q[l+ 0] >> 4) & 3)
|
520 |
+
+ y[l+96] * d[6] * ((q[l+ 0] >> 6) & 3)
|
521 |
+
+ y[l+16] * d[1] * ((q[l+16] >> 0) & 3)
|
522 |
+
+ y[l+48] * d[3] * ((q[l+16] >> 2) & 3)
|
523 |
+
+ y[l+80] * d[5] * ((q[l+16] >> 4) & 3)
|
524 |
+
+y[l+112] * d[7] * ((q[l+16] >> 6) & 3);
|
525 |
+
sum2 += y[l+ 0] * m[0] + y[l+32] * m[2] + y[l+64] * m[4] + y[ l+96] * m[6]
|
526 |
+
+ y[l+16] * m[1] + y[l+48] * m[3] + y[l+80] * m[5] + y[l+112] * m[7];
|
527 |
+
|
528 |
+
}
|
529 |
+
tmp += dall * sum1 - dmin * sum2;
|
530 |
+
|
531 |
+
}
|
532 |
+
|
533 |
+
// sum up partial sums and write back result
|
534 |
+
__syncthreads();
|
535 |
+
#pragma unroll
|
536 |
+
for (int mask = 16; mask > 0; mask >>= 1) {
|
537 |
+
tmp += __shfl_xor_sync(0xffffffff, tmp, mask, 32);
|
538 |
+
}
|
539 |
+
|
540 |
+
if (tid == 0) {
|
541 |
+
dst[row] = tmp;
|
542 |
+
}
|
543 |
+
}
|
544 |
+
|
545 |
+
static __global__ void dequantize_mul_mat_vec_q3_k(const void * vx, const float * yy, float * dst, const int ncols) {
|
546 |
+
|
547 |
+
const uint16_t kmask1 = 0x0303;
|
548 |
+
const uint16_t kmask2 = 0x0f0f;
|
549 |
+
|
550 |
+
const int row = blockIdx.x;
|
551 |
+
const int num_blocks_per_row = ncols / QK_K;
|
552 |
+
const int ib0 = row*num_blocks_per_row;
|
553 |
+
|
554 |
+
const block_q3_K * x = (const block_q3_K *)vx + ib0;
|
555 |
+
|
556 |
+
const int tid = threadIdx.x/2; // 0...15
|
557 |
+
const int ix = threadIdx.x%2; // 0, 1
|
558 |
+
|
559 |
+
const int n = 2; // iterations in the inner loop
|
560 |
+
const int im = tid/8; // 0 or 1. 0 computes 0..., 1 computes 128...
|
561 |
+
const int in = tid - 8*im; // 0...7
|
562 |
+
|
563 |
+
const uint8_t m = 1 << (4*im);
|
564 |
+
|
565 |
+
const int l0 = n*in; // 0...28 in steps of 4
|
566 |
+
const int q_offset = 32*im + l0;
|
567 |
+
const int y_offset = 128*im + l0;
|
568 |
+
|
569 |
+
uint16_t utmp[4];
|
570 |
+
const int8_t * s = (const int8_t *)utmp;
|
571 |
+
|
572 |
+
const uint16_t s_shift = 4*im;
|
573 |
+
|
574 |
+
float tmp = 0; // partial sum for thread in warp
|
575 |
+
|
576 |
+
for (int i = ix; i < num_blocks_per_row; i += 2) {
|
577 |
+
|
578 |
+
const float * y = yy + i * QK_K + y_offset;
|
579 |
+
const uint8_t * q = x[i].qs + q_offset;
|
580 |
+
const uint8_t * h = x[i].hmask + l0;
|
581 |
+
|
582 |
+
const uint16_t * a = (const uint16_t *)x[i].scales;
|
583 |
+
utmp[0] = ((a[0] >> s_shift) & kmask2) | (((a[4] >> (s_shift + 0)) & kmask1) << 4);
|
584 |
+
utmp[1] = ((a[1] >> s_shift) & kmask2) | (((a[5] >> (s_shift + 0)) & kmask1) << 4);
|
585 |
+
utmp[2] = ((a[2] >> s_shift) & kmask2) | (((a[4] >> (s_shift + 2)) & kmask1) << 4);
|
586 |
+
utmp[3] = ((a[3] >> s_shift) & kmask2) | (((a[5] >> (s_shift + 2)) & kmask1) << 4);
|
587 |
+
|
588 |
+
const float d = x[i].d;
|
589 |
+
|
590 |
+
float sum = 0;
|
591 |
+
for (int l = 0; l < n; ++l) {
|
592 |
+
sum += y[l+ 0] * (s[0] - 32) * (((q[l] >> 0) & 3) - (h[l] & (m << 0) ? 0 : 4))
|
593 |
+
+ y[l+32] * (s[2] - 32) * (((q[l] >> 2) & 3) - (h[l] & (m << 1) ? 0 : 4))
|
594 |
+
+ y[l+64] * (s[4] - 32) * (((q[l] >> 4) & 3) - (h[l] & (m << 2) ? 0 : 4))
|
595 |
+
+ y[l+96] * (s[6] - 32) * (((q[l] >> 6) & 3) - (h[l] & (m << 3) ? 0 : 4));
|
596 |
+
sum += y[l+16] * (s[1] - 32) * (((q[l+16] >> 0) & 3) - (h[l+16] & (m << 0) ? 0 : 4))
|
597 |
+
+ y[l+48] * (s[3] - 32) * (((q[l+16] >> 2) & 3) - (h[l+16] & (m << 1) ? 0 : 4))
|
598 |
+
+ y[l+80] * (s[5] - 32) * (((q[l+16] >> 4) & 3) - (h[l+16] & (m << 2) ? 0 : 4))
|
599 |
+
+ y[l+112] * (s[7] - 32) * (((q[l+16] >> 6) & 3) - (h[l+16] & (m << 3) ? 0 : 4));
|
600 |
+
}
|
601 |
+
tmp += d * sum;
|
602 |
+
|
603 |
+
}
|
604 |
+
|
605 |
+
// sum up partial sums and write back result
|
606 |
+
__syncthreads();
|
607 |
+
#pragma unroll
|
608 |
+
for (int mask = 16; mask > 0; mask >>= 1) {
|
609 |
+
tmp += __shfl_xor_sync(0xffffffff, tmp, mask, 32);
|
610 |
+
}
|
611 |
+
|
612 |
+
if (tid == 0) {
|
613 |
+
dst[row] = tmp;
|
614 |
+
}
|
615 |
+
}
|
616 |
+
|
617 |
+
static __global__ void dequantize_mul_mat_vec_q4_k(const void * vx, const float * yy, float * dst, const int ncols) {
|
618 |
+
|
619 |
+
const uint16_t kmask1 = 0x3f3f;
|
620 |
+
const uint16_t kmask2 = 0x0f0f;
|
621 |
+
const uint16_t kmask3 = 0xc0c0;
|
622 |
+
|
623 |
+
const int row = blockIdx.x;
|
624 |
+
const int num_blocks_per_row = ncols / QK_K;
|
625 |
+
const int ib0 = row*num_blocks_per_row;
|
626 |
+
|
627 |
+
const int tid = threadIdx.x/2; // 0...15
|
628 |
+
const int ix = threadIdx.x%2;
|
629 |
+
|
630 |
+
const int il = tid/4; // 0...3
|
631 |
+
const int ir = tid - 4*il;// 0...3
|
632 |
+
const int n = 4;
|
633 |
+
|
634 |
+
const int im = il/2; // 0 or 1. 0 computes 0,32 + 128,160, 1 computes 64,96 + 192,224
|
635 |
+
const int in = il%2;
|
636 |
+
|
637 |
+
const int l0 = n*(2*ir + in);
|
638 |
+
const int q_offset = 32*im + l0;
|
639 |
+
const int y_offset = 64*im + l0;
|
640 |
+
|
641 |
+
uint16_t aux[4];
|
642 |
+
const uint8_t * sc = (const uint8_t *)aux;
|
643 |
+
|
644 |
+
const block_q4_K * x = (const block_q4_K *)vx + ib0;
|
645 |
+
|
646 |
+
float tmp = 0; // partial sum for thread in warp
|
647 |
+
|
648 |
+
for (int i = ix; i < num_blocks_per_row; i += 2) {
|
649 |
+
|
650 |
+
const uint8_t * q1 = x[i].qs + q_offset;
|
651 |
+
const uint8_t * q2 = q1 + 64;
|
652 |
+
const float * y1 = yy + i*QK_K + y_offset;
|
653 |
+
const float * y2 = y1 + 128;
|
654 |
+
|
655 |
+
const float dall = x[i].d;
|
656 |
+
const float dmin = x[i].dmin;
|
657 |
+
|
658 |
+
const uint16_t * a = (const uint16_t *)x[i].scales;
|
659 |
+
aux[0] = a[im+0] & kmask1;
|
660 |
+
aux[1] = a[im+2] & kmask1;
|
661 |
+
aux[2] = ((a[im+4] >> 0) & kmask2) | ((a[im+0] & kmask3) >> 2);
|
662 |
+
aux[3] = ((a[im+4] >> 4) & kmask2) | ((a[im+2] & kmask3) >> 2);
|
663 |
+
|
664 |
+
float4 s = {0.f, 0.f, 0.f, 0.f};
|
665 |
+
float smin = 0;
|
666 |
+
for (int l = 0; l < n; ++l) {
|
667 |
+
s.x += y1[l] * (q1[l] & 0xF); s.y += y1[l+32] * (q1[l] >> 4);
|
668 |
+
s.z += y2[l] * (q2[l] & 0xF); s.w += y2[l+32] * (q2[l] >> 4);
|
669 |
+
smin += y1[l] * sc[2] + y1[l+32] * sc[3] + y2[l] * sc[6] + y2[l+32] * sc[7];
|
670 |
+
}
|
671 |
+
tmp += dall * (s.x * sc[0] + s.y * sc[1] + s.z * sc[4] + s.w * sc[5]) - dmin * smin;
|
672 |
+
|
673 |
+
}
|
674 |
+
|
675 |
+
// sum up partial sums and write back result
|
676 |
+
__syncthreads();
|
677 |
+
#pragma unroll
|
678 |
+
for (int mask = 16; mask > 0; mask >>= 1) {
|
679 |
+
tmp += __shfl_xor_sync(0xffffffff, tmp, mask, 32);
|
680 |
+
}
|
681 |
+
|
682 |
+
if (tid == 0) {
|
683 |
+
dst[row] = tmp;
|
684 |
+
}
|
685 |
+
}
|
686 |
+
|
687 |
+
static __global__ void dequantize_mul_mat_vec_q5_k(const void * vx, const float * yy, float * dst, const int ncols) {
|
688 |
+
|
689 |
+
const uint16_t kmask1 = 0x3f3f;
|
690 |
+
const uint16_t kmask2 = 0x0f0f;
|
691 |
+
const uint16_t kmask3 = 0xc0c0;
|
692 |
+
|
693 |
+
//const int row = blockIdx.x*blockDim.y + threadIdx.y;
|
694 |
+
const int row = blockIdx.x;
|
695 |
+
const int num_blocks_per_row = ncols / QK_K;
|
696 |
+
const int ib0 = row*num_blocks_per_row;
|
697 |
+
|
698 |
+
const int tid = threadIdx.x/2; // 0...15
|
699 |
+
const int ix = threadIdx.x%2;
|
700 |
+
|
701 |
+
const int il = tid/4; // 0...3
|
702 |
+
const int ir = tid - 4*il;// 0...3
|
703 |
+
const int n = 4;
|
704 |
+
|
705 |
+
const int im = il/2; // 0 or 1. 0 computes 0,32 + 128,160, 1 computes 64,96 + 192,224
|
706 |
+
const int in = il%2;
|
707 |
+
|
708 |
+
const int l0 = n*(2*ir + in);
|
709 |
+
const int q_offset = 32*im + l0;
|
710 |
+
const int y_offset = 64*im + l0;
|
711 |
+
|
712 |
+
const uint8_t hm1 = 1 << (2*im);
|
713 |
+
const uint8_t hm2 = hm1 << 4;
|
714 |
+
|
715 |
+
uint16_t aux[4];
|
716 |
+
const uint8_t * sc = (const uint8_t *)aux;
|
717 |
+
|
718 |
+
const block_q5_K * x = (const block_q5_K *)vx + ib0;
|
719 |
+
|
720 |
+
float tmp = 0; // partial sum for thread in warp
|
721 |
+
|
722 |
+
for (int i = ix; i < num_blocks_per_row; i += 2) {
|
723 |
+
|
724 |
+
const uint8_t * ql1 = x[i].qs + q_offset;
|
725 |
+
const uint8_t * ql2 = ql1 + 64;
|
726 |
+
const uint8_t * qh = x[i].qh + l0;
|
727 |
+
const float * y1 = yy + i*QK_K + y_offset;
|
728 |
+
const float * y2 = y1 + 128;
|
729 |
+
|
730 |
+
const float dall = x[i].d;
|
731 |
+
const float dmin = x[i].dmin;
|
732 |
+
|
733 |
+
const uint16_t * a = (const uint16_t *)x[i].scales;
|
734 |
+
aux[0] = a[im+0] & kmask1;
|
735 |
+
aux[1] = a[im+2] & kmask1;
|
736 |
+
aux[2] = ((a[im+4] >> 0) & kmask2) | ((a[im+0] & kmask3) >> 2);
|
737 |
+
aux[3] = ((a[im+4] >> 4) & kmask2) | ((a[im+2] & kmask3) >> 2);
|
738 |
+
|
739 |
+
float4 sum = {0.f, 0.f, 0.f, 0.f};
|
740 |
+
float smin = 0;
|
741 |
+
for (int l = 0; l < n; ++l) {
|
742 |
+
sum.x += y1[l+ 0] * ((ql1[l] & 0xF) + (qh[l] & (hm1 << 0) ? 16 : 0));
|
743 |
+
sum.y += y1[l+32] * ((ql1[l] >> 4) + (qh[l] & (hm1 << 1) ? 16 : 0));
|
744 |
+
sum.z += y2[l+ 0] * ((ql2[l] & 0xF) + (qh[l] & (hm2 << 0) ? 16 : 0));
|
745 |
+
sum.w += y2[l+32] * ((ql2[l] >> 4) + (qh[l] & (hm2 << 1) ? 16 : 0));
|
746 |
+
smin += y1[l] * sc[2] + y1[l+32] * sc[3] + y2[l] * sc[6] + y2[l+32] * sc[7];
|
747 |
+
}
|
748 |
+
tmp += dall * (sum.x * sc[0] + sum.y * sc[1] + sum.z * sc[4] + sum.w * sc[5]) - dmin * smin;
|
749 |
+
|
750 |
+
}
|
751 |
+
|
752 |
+
// sum up partial sums and write back result
|
753 |
+
__syncthreads();
|
754 |
+
#pragma unroll
|
755 |
+
for (int mask = 16; mask > 0; mask >>= 1) {
|
756 |
+
tmp += __shfl_xor_sync(0xffffffff, tmp, mask, 32);
|
757 |
+
}
|
758 |
+
|
759 |
+
if (tid == 0) {
|
760 |
+
dst[row] = tmp;
|
761 |
+
}
|
762 |
+
}
|
763 |
+
|
764 |
+
static __global__ void dequantize_mul_mat_vec_q6_k(const void * vx, const float * yy, float * dst, const int ncols, int nrows) {
|
765 |
+
|
766 |
+
static_assert(16%K_QUANTS_PER_ITERATION == 0, "16 must be divisible by K_QUANTS_PER_ITERATION");
|
767 |
+
|
768 |
+
const int row = blockIdx.y*blockDim.y + threadIdx.y;
|
769 |
+
if (row > nrows) return;
|
770 |
+
|
771 |
+
const int num_blocks_per_row = ncols / QK_K;
|
772 |
+
const int ib0 = row*num_blocks_per_row;
|
773 |
+
|
774 |
+
const block_q6_K * x = (const block_q6_K *)vx + ib0;
|
775 |
+
|
776 |
+
const int tid = threadIdx.x/K_QUANTS_PER_ITERATION; // 0...31 or 0...16
|
777 |
+
const int ix = threadIdx.x%K_QUANTS_PER_ITERATION; // 0 or 0, 1
|
778 |
+
|
779 |
+
const int step = 16/K_QUANTS_PER_ITERATION; // 16 or 8
|
780 |
+
|
781 |
+
const int im = tid/step; // 0 or 1. 0 computes 0..., 1 computes 128...
|
782 |
+
const int in = tid - step*im; // 0...15 or 0...7
|
783 |
+
|
784 |
+
#if K_QUANTS_PER_ITERATION == 1
|
785 |
+
const int l0 = K_QUANTS_PER_ITERATION*in; // 0...15
|
786 |
+
const int is = 0;
|
787 |
+
#else
|
788 |
+
const int l0 = 4 * in; // 0, 4, 8, ..., 28
|
789 |
+
const int is = in / 4;
|
790 |
+
#endif
|
791 |
+
const int ql_offset = 64*im + l0;
|
792 |
+
const int qh_offset = 32*im + l0;
|
793 |
+
const int s_offset = 8*im + is;
|
794 |
+
const int y_offset = 128*im + l0;
|
795 |
+
|
796 |
+
float tmp = 0; // partial sum for thread in warp
|
797 |
+
|
798 |
+
for (int i = ix; i < num_blocks_per_row; i += K_QUANTS_PER_ITERATION) {
|
799 |
+
|
800 |
+
const float * y = yy + i * QK_K + y_offset;
|
801 |
+
const uint8_t * ql = x[i].ql + ql_offset;
|
802 |
+
const uint8_t * qh = x[i].qh + qh_offset;
|
803 |
+
const int8_t * s = x[i].scales + s_offset;
|
804 |
+
|
805 |
+
const float d = x[i].d;
|
806 |
+
|
807 |
+
#if K_QUANTS_PER_ITERATION == 1
|
808 |
+
float sum = y[ 0] * s[0] * d * ((int8_t)((ql[ 0] & 0xF) | ((qh[ 0] & 0x03) << 4)) - 32)
|
809 |
+
+ y[16] * s[1] * d * ((int8_t)((ql[16] & 0xF) | ((qh[16] & 0x03) << 4)) - 32)
|
810 |
+
+ y[32] * s[2] * d * ((int8_t)((ql[32] & 0xF) | ((qh[ 0] & 0x0c) << 2)) - 32)
|
811 |
+
+ y[48] * s[3] * d * ((int8_t)((ql[48] & 0xF) | ((qh[16] & 0x0c) << 2)) - 32)
|
812 |
+
+ y[64] * s[4] * d * ((int8_t)((ql[ 0] >> 4) | ((qh[ 0] & 0x30) >> 0)) - 32)
|
813 |
+
+ y[80] * s[5] * d * ((int8_t)((ql[16] >> 4) | ((qh[16] & 0x30) >> 0)) - 32)
|
814 |
+
+ y[96] * s[6] * d * ((int8_t)((ql[32] >> 4) | ((qh[ 0] & 0xc0) >> 2)) - 32)
|
815 |
+
+y[112] * s[7] * d * ((int8_t)((ql[48] >> 4) | ((qh[16] & 0xc0) >> 2)) - 32);
|
816 |
+
tmp += sum;
|
817 |
+
#else
|
818 |
+
float sum = 0;
|
819 |
+
for (int l = 0; l < 4; ++l) {
|
820 |
+
sum += y[l+ 0] * s[0] * d * ((int8_t)((ql[l+ 0] & 0xF) | (((qh[l] >> 0) & 3) << 4)) - 32)
|
821 |
+
+ y[l+32] * s[2] * d * ((int8_t)((ql[l+32] & 0xF) | (((qh[l] >> 2) & 3) << 4)) - 32)
|
822 |
+
+ y[l+64] * s[4] * d * ((int8_t)((ql[l+ 0] >> 4) | (((qh[l] >> 4) & 3) << 4)) - 32)
|
823 |
+
+ y[l+96] * s[6] * d * ((int8_t)((ql[l+32] >> 4) | (((qh[l] >> 6) & 3) << 4)) - 32);
|
824 |
+
}
|
825 |
+
tmp += sum;
|
826 |
+
#endif
|
827 |
|
828 |
+
}
|
|
|
|
|
829 |
|
830 |
+
// sum up partial sums and write back result
|
831 |
+
__syncthreads();
|
832 |
+
#pragma unroll
|
833 |
+
for (int mask = 16; mask > 0; mask >>= 1) {
|
834 |
+
tmp += __shfl_xor_sync(0xffffffff, tmp, mask, 32);
|
835 |
+
}
|
|
|
|
|
836 |
|
837 |
+
if (tid == 0) {
|
838 |
+
dst[row] = tmp;
|
839 |
+
}
|
840 |
}
|
841 |
|
842 |
static __device__ void convert_f16(const void * vx, const int ib, const int iqs, float & v0, float & v1){
|
|
|
866 |
}
|
867 |
|
868 |
template <int qk, int qr, dequantize_kernel_t dequantize_kernel>
|
869 |
+
static __global__ void dequantize_mul_mat_vec(const void * vx, const float * y, float * dst, const int ncols, const int nrows) {
|
870 |
// qk = quantized weights per x block
|
871 |
// qr = number of quantized weights per data value in x block
|
872 |
+
const int row = blockIdx.y*blockDim.y + threadIdx.y;
|
873 |
+
|
874 |
+
if (row >= nrows) {
|
875 |
+
return;
|
876 |
+
}
|
877 |
+
|
878 |
const int tid = threadIdx.x;
|
879 |
|
880 |
const int iter_stride = 2*GGML_CUDA_DMMV_X;
|
|
|
918 |
}
|
919 |
}
|
920 |
|
921 |
+
static __global__ void mul_mat_p021_f16_f32(const void * vx, const float * y, float * dst, const int ncols_x, const int nrows_x, const int nchannels_x) {
|
922 |
+
const half * x = (half *) vx;
|
|
|
|
|
923 |
|
924 |
+
const int row_x = blockDim.y*blockIdx.y + threadIdx.y;
|
925 |
+
const int channel = blockDim.z*blockIdx.z + threadIdx.z;
|
|
|
|
|
926 |
|
927 |
+
const int nrows_y = ncols_x;
|
928 |
+
const int nrows_dst = nrows_x;
|
929 |
+
const int row_dst = row_x;
|
930 |
|
931 |
+
float tmp = 0.0f;
|
932 |
+
|
933 |
+
for (int col_x0 = 0; col_x0 < ncols_x; col_x0 += blockDim.x) {
|
934 |
+
const int col_x = col_x0 + threadIdx.x;
|
935 |
+
|
936 |
+
if (col_x >= ncols_x) {
|
937 |
+
break;
|
938 |
+
}
|
939 |
+
|
940 |
+
// x is transposed and permuted
|
941 |
+
const int ix = row_x*nchannels_x*ncols_x + channel*ncols_x + col_x;
|
942 |
+
const float xi = __half2float(x[ix]);
|
943 |
+
|
944 |
+
const int row_y = col_x;
|
945 |
+
|
946 |
+
|
947 |
+
// y is not transposed but permuted
|
948 |
+
const int iy = channel*nrows_y + row_y;
|
949 |
+
|
950 |
+
tmp += xi * y[iy];
|
951 |
+
}
|
952 |
+
|
953 |
+
// dst is not transposed and not permuted
|
954 |
+
const int idst = channel*nrows_dst + row_dst;
|
955 |
+
|
956 |
+
// sum up partial sums and write back result
|
957 |
+
__syncthreads();
|
958 |
+
#pragma unroll
|
959 |
+
for (int mask = 16; mask > 0; mask >>= 1) {
|
960 |
+
tmp += __shfl_xor_sync(0xffffffff, tmp, mask, 32);
|
961 |
+
}
|
962 |
+
|
963 |
+
if (threadIdx.x == 0) {
|
964 |
+
dst[idst] = tmp;
|
965 |
+
}
|
966 |
+
}
|
967 |
+
|
968 |
+
static __global__ void mul_mat_vec_nc_f16_f32( // nc == non-contiguous
|
969 |
+
const void * vx, const float * y, float * dst, const int ncols_x, const int nrows_x,
|
970 |
+
const int row_stride_x, const int nchannels_x, const int channel_stride_x) {
|
971 |
+
|
972 |
+
const half * x = (half *) vx;
|
973 |
+
|
974 |
+
const int row_x = blockDim.y*blockIdx.y + threadIdx.y;
|
975 |
+
const int channel = blockDim.z*blockIdx.z + threadIdx.z;
|
976 |
+
|
977 |
+
const int nrows_y = ncols_x;
|
978 |
+
const int nrows_dst = nrows_x;
|
979 |
+
const int row_dst = row_x;
|
980 |
|
981 |
+
const int idst = channel*nrows_dst + row_dst;
|
982 |
+
|
983 |
+
float tmp = 0.0f;
|
984 |
+
|
985 |
+
for (int col_x0 = 0; col_x0 < ncols_x; col_x0 += blockDim.x) {
|
986 |
+
const int col_x = col_x0 + threadIdx.x;
|
987 |
+
|
988 |
+
if (col_x >= ncols_x) {
|
989 |
+
break;
|
990 |
+
}
|
991 |
+
|
992 |
+
const int ix = channel*channel_stride_x + row_x*row_stride_x + col_x;
|
993 |
+
const float xi = __half2float(x[ix]);
|
994 |
+
|
995 |
+
const int row_y = col_x;
|
996 |
+
|
997 |
+
const int iy = channel*nrows_y + row_y;
|
998 |
+
|
999 |
+
tmp += xi * y[iy];
|
1000 |
}
|
1001 |
|
1002 |
// sum up partial sums and write back result
|
|
|
1006 |
tmp += __shfl_xor_sync(0xffffffff, tmp, mask, 32);
|
1007 |
}
|
1008 |
|
1009 |
+
if (threadIdx.x == 0) {
|
1010 |
+
dst[idst] = tmp;
|
1011 |
+
}
|
1012 |
+
}
|
1013 |
+
|
1014 |
+
static __device__ void cpy_1_f32_f32(const char * cxi, char * cdsti) {
|
1015 |
+
const float * xi = (float *) cxi;
|
1016 |
+
float * dsti = (float *) cdsti;
|
1017 |
+
|
1018 |
+
*dsti = *xi;
|
1019 |
+
}
|
1020 |
+
|
1021 |
+
static __device__ void cpy_1_f32_f16(const char * cxi, char * cdsti) {
|
1022 |
+
const float * xi = (float *) cxi;
|
1023 |
+
half * dsti = (half *) cdsti;
|
1024 |
+
|
1025 |
+
*dsti = __float2half(*xi);
|
1026 |
+
}
|
1027 |
+
|
1028 |
+
template <cpy_kernel_t cpy_1>
|
1029 |
+
static __global__ void cpy_f32_f16(const char * cx, char * cdst, const int ne,
|
1030 |
+
const int ne00, const int ne01, const int nb00, const int nb01, const int nb02,
|
1031 |
+
const int ne10, const int ne11, const int nb10, const int nb11, const int nb12) {
|
1032 |
+
const int i = blockDim.x*blockIdx.x + threadIdx.x;
|
1033 |
+
|
1034 |
+
if (i >= ne) {
|
1035 |
+
return;
|
1036 |
}
|
1037 |
+
|
1038 |
+
// determine indices i02/i12, i01/i11, i00/i10 as a function of index i of flattened tensor
|
1039 |
+
// then combine those indices with the corresponding byte offsets to get the total offsets
|
1040 |
+
const int i02 = i / (ne00*ne01);
|
1041 |
+
const int i01 = (i - i02*ne01*ne00) / ne00;
|
1042 |
+
const int i00 = i - i02*ne01*ne00 - i01*ne00;
|
1043 |
+
const int x_offset = i00*nb00 + i01*nb01 + i02*nb02;
|
1044 |
+
|
1045 |
+
const int i12 = i / (ne10*ne11);
|
1046 |
+
const int i11 = (i - i12*ne10*ne11) / ne10;
|
1047 |
+
const int i10 = i - i12*ne10*ne11 - i11*ne10;
|
1048 |
+
const int dst_offset = i10*nb10 + i11*nb11 + i12*nb12;
|
1049 |
+
|
1050 |
+
cpy_1(cx + x_offset, cdst + dst_offset);
|
1051 |
}
|
1052 |
|
1053 |
+
// rope == RoPE == rotary positional embedding
|
1054 |
static __global__ void rope_f32(const float * x, float * dst, const int ncols, const float p, const float theta_scale) {
|
1055 |
const int col = 2*(blockDim.x*blockIdx.x + threadIdx.x);
|
1056 |
|
|
|
1072 |
dst[i + 1] = x0*sin_theta + x1*cos_theta;
|
1073 |
}
|
1074 |
|
1075 |
+
static __global__ void diag_mask_inf_f32(const float * x, float * dst, const int ncols, const int rows_per_channel, const int n_past) {
|
1076 |
+
const int col = blockDim.x*blockIdx.x + threadIdx.x;
|
1077 |
+
const int row = blockDim.y*blockIdx.y + threadIdx.y;
|
1078 |
+
|
1079 |
+
if (col >= ncols) {
|
1080 |
+
return;
|
1081 |
+
}
|
1082 |
+
|
1083 |
+
const int i = row*ncols + col;
|
1084 |
+
// dst[i] = col > n_past + row ? -INFINITY : x[i];
|
1085 |
+
dst[i] = x[i] - (col > n_past + row % rows_per_channel) * INT_MAX; // equivalent within rounding error but slightly faster on GPU
|
1086 |
+
}
|
1087 |
+
|
1088 |
+
// the CUDA soft max implementation differs from the CPU implementation
|
1089 |
+
// instead of doubles floats are used
|
1090 |
+
// values are also not normalized to the maximum value by subtracting it in the exponential function
|
1091 |
+
// theoretically these changes could cause problems with rounding error and arithmetic overflow but for LLaMa it seems to be fine
|
1092 |
+
static __global__ void soft_max_f32(const float * x, float * dst, const int ncols) {
|
1093 |
+
const int row = blockDim.y*blockIdx.y + threadIdx.y;
|
1094 |
+
const int block_size = blockDim.x;
|
1095 |
+
const int tid = threadIdx.x;
|
1096 |
+
|
1097 |
+
float tmp = 0.0;
|
1098 |
+
|
1099 |
+
for (int block_start = 0; block_start < ncols; block_start += block_size) {
|
1100 |
+
const int col = block_start + tid;
|
1101 |
+
|
1102 |
+
if (col >= ncols) {
|
1103 |
+
break;
|
1104 |
+
}
|
1105 |
+
|
1106 |
+
const int i = row*ncols + col;
|
1107 |
+
const float val = expf(x[i]);
|
1108 |
+
tmp += val;
|
1109 |
+
dst[i] = val;
|
1110 |
+
}
|
1111 |
+
|
1112 |
+
// sum up partial sums
|
1113 |
+
__syncthreads();
|
1114 |
+
#pragma unroll
|
1115 |
+
for (int mask = 16; mask > 0; mask >>= 1) {
|
1116 |
+
tmp += __shfl_xor_sync(0xffffffff, tmp, mask, 32);
|
1117 |
+
}
|
1118 |
+
|
1119 |
+
for (int block_start = 0; block_start < ncols; block_start += block_size) {
|
1120 |
+
const int col = block_start + tid;
|
1121 |
+
|
1122 |
+
if (col >= ncols) {
|
1123 |
+
break;
|
1124 |
+
}
|
1125 |
+
|
1126 |
+
const int i = row*ncols + col;
|
1127 |
+
dst[i] /= tmp;
|
1128 |
+
}
|
1129 |
+
}
|
1130 |
+
|
1131 |
+
static __global__ void scale_f32(const float * x, float * dst, const float scale, const int k) {
|
1132 |
+
const int i = blockDim.x*blockIdx.x + threadIdx.x;
|
1133 |
+
|
1134 |
+
if (i >= k) {
|
1135 |
+
return;
|
1136 |
+
}
|
1137 |
+
|
1138 |
+
dst[i] = scale * x[i];
|
1139 |
+
}
|
1140 |
+
|
1141 |
static void add_f32_cuda(const float * x, const float * y, float * dst, const int k, cudaStream_t stream) {
|
1142 |
const int num_blocks = (k + CUDA_ADD_BLOCK_SIZE - 1) / CUDA_ADD_BLOCK_SIZE;
|
1143 |
add_f32<<<num_blocks, CUDA_ADD_BLOCK_SIZE, 0, stream>>>(x, y, dst, k);
|
|
|
1211 |
|
1212 |
static void dequantize_mul_mat_vec_q4_0_cuda(const void * vx, const float * y, float * dst, const int ncols, const int nrows, cudaStream_t stream) {
|
1213 |
GGML_ASSERT(ncols % GGML_CUDA_DMMV_X == 0);
|
1214 |
+
const int block_num_y = (nrows + GGML_CUDA_DMMV_Y - 1) / GGML_CUDA_DMMV_Y;
|
1215 |
+
const dim3 block_nums(1, block_num_y, 1);
|
1216 |
const dim3 block_dims(WARP_SIZE, GGML_CUDA_DMMV_Y, 1);
|
1217 |
dequantize_mul_mat_vec<QK4_0, QR4_0, dequantize_q4_0>
|
1218 |
+
<<<block_nums, block_dims, 0, stream>>>(vx, y, dst, ncols, nrows);
|
1219 |
}
|
1220 |
|
1221 |
static void dequantize_mul_mat_vec_q4_1_cuda(const void * vx, const float * y, float * dst, const int ncols, const int nrows, cudaStream_t stream) {
|
1222 |
GGML_ASSERT(ncols % GGML_CUDA_DMMV_X == 0);
|
1223 |
+
const int block_num_y = (nrows + GGML_CUDA_DMMV_Y - 1) / GGML_CUDA_DMMV_Y;
|
1224 |
+
const dim3 block_nums(1, block_num_y, 1);
|
1225 |
const dim3 block_dims(WARP_SIZE, GGML_CUDA_DMMV_Y, 1);
|
1226 |
dequantize_mul_mat_vec<QK4_1, QR4_1, dequantize_q4_1>
|
1227 |
+
<<<block_nums, block_dims, 0, stream>>>(vx, y, dst, ncols, nrows);
|
1228 |
}
|
1229 |
|
1230 |
static void dequantize_mul_mat_vec_q5_0_cuda(const void * vx, const float * y, float * dst, const int ncols, const int nrows, cudaStream_t stream) {
|
1231 |
GGML_ASSERT(ncols % GGML_CUDA_DMMV_X == 0);
|
1232 |
+
const int block_num_y = (nrows + GGML_CUDA_DMMV_Y - 1) / GGML_CUDA_DMMV_Y;
|
1233 |
+
const dim3 block_nums(1, block_num_y, 1);
|
1234 |
const dim3 block_dims(WARP_SIZE, GGML_CUDA_DMMV_Y, 1);
|
1235 |
dequantize_mul_mat_vec<QK5_0, QR5_0, dequantize_q5_0>
|
1236 |
+
<<<block_nums, block_dims, 0, stream>>>(vx, y, dst, ncols, nrows);
|
1237 |
}
|
1238 |
|
1239 |
static void dequantize_mul_mat_vec_q5_1_cuda(const void * vx, const float * y, float * dst, const int ncols, const int nrows, cudaStream_t stream) {
|
1240 |
GGML_ASSERT(ncols % GGML_CUDA_DMMV_X == 0);
|
1241 |
+
const int block_num_y = (nrows + GGML_CUDA_DMMV_Y - 1) / GGML_CUDA_DMMV_Y;
|
1242 |
+
const dim3 block_nums(1, block_num_y, 1);
|
1243 |
const dim3 block_dims(WARP_SIZE, GGML_CUDA_DMMV_Y, 1);
|
1244 |
dequantize_mul_mat_vec<QK5_1, QR5_1, dequantize_q5_1>
|
1245 |
+
<<<block_nums, block_dims, 0, stream>>>(vx, y, dst, ncols, nrows);
|
1246 |
}
|
1247 |
|
1248 |
static void dequantize_mul_mat_vec_q8_0_cuda(const void * vx, const float * y, float * dst, const int ncols, const int nrows, cudaStream_t stream) {
|
1249 |
GGML_ASSERT(ncols % GGML_CUDA_DMMV_X == 0);
|
1250 |
+
const int block_num_y = (nrows + GGML_CUDA_DMMV_Y - 1) / GGML_CUDA_DMMV_Y;
|
1251 |
+
const dim3 block_nums(1, block_num_y, 1);
|
1252 |
const dim3 block_dims(WARP_SIZE, GGML_CUDA_DMMV_Y, 1);
|
1253 |
dequantize_mul_mat_vec<QK8_0, QR8_0, dequantize_q8_0>
|
1254 |
+
<<<block_nums, block_dims, 0, stream>>>(vx, y, dst, ncols, nrows);
|
1255 |
}
|
1256 |
|
1257 |
static void dequantize_mul_mat_vec_q2_K_cuda(const void * vx, const float * y, float * dst, const int ncols, const int nrows, cudaStream_t stream) {
|
1258 |
GGML_ASSERT(ncols % QK_K == 0);
|
1259 |
const int ny = 2;
|
1260 |
+
const int block_num_y = (nrows + ny - 1) / ny;
|
1261 |
+
const dim3 block_nums(1, block_num_y, 1);
|
1262 |
const dim3 block_dims(32, ny, 1);
|
1263 |
+
dequantize_mul_mat_vec_q2_k<<<block_nums, block_dims, 0, stream>>>(vx, y, dst, ncols, nrows);
|
1264 |
}
|
1265 |
|
1266 |
static void dequantize_mul_mat_vec_q3_K_cuda(const void * vx, const float * y, float * dst, const int ncols, const int nrows, cudaStream_t stream) {
|
1267 |
GGML_ASSERT(ncols % QK_K == 0);
|
1268 |
+
const dim3 block_dims(32, 1, 1);
|
1269 |
+
dequantize_mul_mat_vec_q3_k<<<nrows, block_dims, 0, stream>>>(vx, y, dst, ncols);
|
1270 |
}
|
1271 |
|
1272 |
static void dequantize_mul_mat_vec_q4_K_cuda(const void * vx, const float * y, float * dst, const int ncols, const int nrows, cudaStream_t stream) {
|
1273 |
GGML_ASSERT(ncols % QK_K == 0);
|
1274 |
+
const dim3 block_dims(32, 1, 1);
|
1275 |
+
dequantize_mul_mat_vec_q4_k<<<nrows, block_dims, 0, stream>>>(vx, y, dst, ncols);
|
1276 |
}
|
1277 |
|
1278 |
static void dequantize_mul_mat_vec_q5_K_cuda(const void * vx, const float * y, float * dst, const int ncols, const int nrows, cudaStream_t stream) {
|
1279 |
GGML_ASSERT(ncols % QK_K == 0);
|
1280 |
+
const dim3 block_dims(32, 1, 1);
|
1281 |
+
dequantize_mul_mat_vec_q5_k<<<nrows, block_dims, 0, stream>>>(vx, y, dst, ncols);
|
1282 |
}
|
1283 |
|
1284 |
static void dequantize_mul_mat_vec_q6_K_cuda(const void * vx, const float * y, float * dst, const int ncols, const int nrows, cudaStream_t stream) {
|
1285 |
GGML_ASSERT(ncols % QK_K == 0);
|
1286 |
+
const int ny = 2 / K_QUANTS_PER_ITERATION;
|
1287 |
+
const int block_num_y = (nrows + ny - 1) / ny;
|
1288 |
+
const dim3 block_nums(1, block_num_y, 1);
|
1289 |
+
const dim3 block_dims(32, ny, 1);
|
1290 |
+
dequantize_mul_mat_vec_q6_k<<<block_nums, block_dims, 0, stream>>>(vx, y, dst, ncols, nrows);
|
1291 |
}
|
1292 |
|
1293 |
static void convert_fp16_to_fp32_cuda(const void * vx, float * y, const int k, cudaStream_t stream) {
|
|
|
1297 |
|
1298 |
static void convert_mul_mat_vec_f16_cuda(const void * vx, const float * y, float * dst, const int ncols, const int nrows, cudaStream_t stream) {
|
1299 |
GGML_ASSERT(ncols % GGML_CUDA_DMMV_X == 0);
|
1300 |
+
const int block_num_y = (nrows + GGML_CUDA_DMMV_Y - 1) / GGML_CUDA_DMMV_Y;
|
1301 |
+
const dim3 block_nums(1, block_num_y, 1);
|
1302 |
const dim3 block_dims(WARP_SIZE, GGML_CUDA_DMMV_Y, 1);
|
1303 |
dequantize_mul_mat_vec<1, 1, convert_f16>
|
1304 |
+
<<<block_nums, block_dims, 0, stream>>>(vx, y, dst, ncols, nrows);
|
1305 |
}
|
1306 |
|
1307 |
static to_fp32_cuda_t ggml_get_to_fp32_cuda(ggml_type type) {
|
|
|
1333 |
}
|
1334 |
}
|
1335 |
|
1336 |
+
static void ggml_mul_mat_p021_f16_f32_cuda(const void * vx, const float * y, float * dst, const int ncols_x, const int nrows_x, const int nchannels_x, cudaStream_t stream) {
|
1337 |
+
const dim3 block_nums(1, nrows_x, nchannels_x);
|
1338 |
+
const dim3 block_dims(WARP_SIZE, 1, 1);
|
1339 |
+
mul_mat_p021_f16_f32<<<block_nums, block_dims, 0, stream>>>(vx, y, dst, ncols_x, nrows_x, nchannels_x);
|
1340 |
+
}
|
1341 |
+
|
1342 |
+
static void ggml_mul_mat_vec_nc_f16_f32_cuda(
|
1343 |
+
const void * vx, const float * y, float * dst, const int ncols_x, const int nrows_x, const int row_stride_x,
|
1344 |
+
const int nchannels_x, const int channel_stride_x, cudaStream_t stream) {
|
1345 |
+
|
1346 |
+
const dim3 block_nums(1, nrows_x, nchannels_x);
|
1347 |
+
const dim3 block_dims(WARP_SIZE, 1, 1);
|
1348 |
+
mul_mat_vec_nc_f16_f32<<<block_nums, block_dims, 0, stream>>>
|
1349 |
+
(vx, y, dst, ncols_x, nrows_x, row_stride_x, nchannels_x, channel_stride_x);
|
1350 |
+
}
|
1351 |
+
|
1352 |
+
static void ggml_cpy_f32_f32_cuda(
|
1353 |
+
const char * cx, char * cdst, const int ne,
|
1354 |
+
const int ne00, const int ne01, const int nb00, const int nb01, const int nb02,
|
1355 |
+
const int ne10, const int ne11, const int nb10, const int nb11, const int nb12, cudaStream_t stream) {
|
1356 |
+
|
1357 |
+
const int num_blocks = (ne + CUDA_CPY_BLOCK_SIZE - 1) / CUDA_CPY_BLOCK_SIZE;
|
1358 |
+
cpy_f32_f16<cpy_1_f32_f32><<<num_blocks, CUDA_CPY_BLOCK_SIZE, 0, stream>>>
|
1359 |
+
(cx, cdst, ne, ne00, ne01, nb00, nb01, nb02, ne10, ne11, nb10, nb11, nb12);
|
1360 |
+
}
|
1361 |
+
|
1362 |
+
static void ggml_cpy_f32_f16_cuda(
|
1363 |
+
const char * cx, char * cdst, const int ne,
|
1364 |
+
const int ne00, const int ne01, const int nb00, const int nb01, const int nb02,
|
1365 |
+
const int ne10, const int ne11, const int nb10, const int nb11, const int nb12, cudaStream_t stream) {
|
1366 |
+
|
1367 |
+
const int num_blocks = (ne + CUDA_CPY_BLOCK_SIZE - 1) / CUDA_CPY_BLOCK_SIZE;
|
1368 |
+
cpy_f32_f16<cpy_1_f32_f16><<<num_blocks, CUDA_CPY_BLOCK_SIZE, 0, stream>>>
|
1369 |
+
(cx, cdst, ne, ne00, ne01, nb00, nb01, nb02, ne10, ne11, nb10, nb11, nb12);
|
1370 |
+
}
|
1371 |
+
|
1372 |
+
static void scale_f32_cuda(const float * x, float * dst, const float scale, const int k, cudaStream_t stream) {
|
1373 |
+
const int num_blocks = (k + CUDA_SCALE_BLOCK_SIZE - 1) / CUDA_SCALE_BLOCK_SIZE;
|
1374 |
+
scale_f32<<<num_blocks, CUDA_SCALE_BLOCK_SIZE, 0, stream>>>(x, dst, scale, k);
|
1375 |
+
}
|
1376 |
+
|
1377 |
static void rope_f32_cuda(const float * x, float * dst, const int ncols, const int nrows, const float p, const float theta_scale, cudaStream_t stream) {
|
1378 |
GGML_ASSERT(nrows % 2 == 0);
|
1379 |
const dim3 block_dims(2*CUDA_ROPE_BLOCK_SIZE, 1, 1);
|
|
|
1382 |
rope_f32<<<block_nums, block_dims, 0, stream>>>(x, dst, ncols, p, theta_scale);
|
1383 |
}
|
1384 |
|
1385 |
+
static void diag_mask_inf_f32_cuda(const float * x, float * dst, const int ncols_x, const int nrows_x, const int rows_per_channel, const int n_past, cudaStream_t stream) {
|
1386 |
+
const dim3 block_dims(CUDA_DIAG_MASK_INF_BLOCK_SIZE, 1, 1);
|
1387 |
+
const int block_num_x = (ncols_x + CUDA_DIAG_MASK_INF_BLOCK_SIZE - 1) / CUDA_DIAG_MASK_INF_BLOCK_SIZE;
|
1388 |
+
const dim3 block_nums(block_num_x, nrows_x, 1);
|
1389 |
+
diag_mask_inf_f32<<<block_nums, block_dims, 0, stream>>>(x, dst, ncols_x, rows_per_channel, n_past);
|
1390 |
+
}
|
1391 |
+
|
1392 |
+
static void soft_max_f32_cuda(const float * x, float * dst, const int ncols_x, const int nrows_x, cudaStream_t stream) {
|
1393 |
+
const dim3 block_dims(WARP_SIZE, 1, 1);
|
1394 |
+
const dim3 block_nums(1, nrows_x, 1);
|
1395 |
+
soft_max_f32<<<block_nums, block_dims, 0, stream>>>(x, dst, ncols_x);
|
1396 |
+
}
|
1397 |
+
|
1398 |
// buffer pool for cuda
|
1399 |
#define MAX_CUDA_BUFFERS 256
|
1400 |
|
|
|
1565 |
CUDA_CHECK(cudaFreeHost(ptr));
|
1566 |
}
|
1567 |
|
1568 |
+
static cudaError_t ggml_cuda_cpy_tensor_2d(
|
1569 |
void * dst, const struct ggml_tensor * src, int64_t i3, int64_t i2, int64_t i1_low, int64_t i1_high, cudaStream_t stream) {
|
1570 |
|
1571 |
+
cudaMemcpyKind kind;
|
1572 |
+
char * src_ptr;
|
1573 |
+
if (src->backend == GGML_BACKEND_CPU) {
|
1574 |
+
kind = cudaMemcpyHostToDevice;
|
1575 |
+
src_ptr = (char *) src->data;
|
1576 |
+
} else if (src->backend == GGML_BACKEND_GPU) {
|
1577 |
+
kind = cudaMemcpyDeviceToDevice;
|
1578 |
+
struct ggml_tensor_extra_gpu * extra = (ggml_tensor_extra_gpu *) src->extra;
|
1579 |
+
int id;
|
1580 |
+
CUDA_CHECK(cudaGetDevice(&id));
|
1581 |
+
src_ptr = (char *) extra->data_device[id];
|
1582 |
+
} else {
|
1583 |
+
GGML_ASSERT(false);
|
1584 |
+
}
|
1585 |
+
char * dst_ptr = (char *) dst;
|
1586 |
+
|
1587 |
const int64_t ne0 = src->ne[0];
|
1588 |
const int64_t nb0 = src->nb[0];
|
1589 |
const int64_t nb1 = src->nb[1];
|
|
|
1594 |
const int64_t bs = ggml_blck_size(type);
|
1595 |
int64_t i1_diff = i1_high - i1_low;
|
1596 |
|
1597 |
+
const char * x = src_ptr + i1_low*nb1 + i2*nb2 + i3*nb3;
|
1598 |
if (nb0 == ts && nb1 == ts*ne0/bs) {
|
1599 |
+
return cudaMemcpyAsync(dst_ptr, x, i1_diff*nb1, kind, stream);
|
1600 |
} else if (nb0 == ts) {
|
1601 |
+
return cudaMemcpy2DAsync(dst_ptr, ts*ne0/bs, x, nb1, ts*ne0/bs, i1_diff, kind, stream);
|
1602 |
} else {
|
1603 |
for (int64_t i1 = 0; i1 < i1_diff; i1++) {
|
1604 |
const void * rx = (const void *) ((const char *) x + i1*nb1);
|
1605 |
+
void * rd = (void *) (dst_ptr + i1*ts*ne0/bs);
|
1606 |
// pretend the row is a matrix with cols=1
|
1607 |
+
cudaError_t r = cudaMemcpy2DAsync(rd, ts/bs, rx, nb0, ts/bs, ne0, kind, stream);
|
1608 |
if (r != cudaSuccess) return r;
|
1609 |
}
|
1610 |
return cudaSuccess;
|
|
|
1840 |
(void) i1;
|
1841 |
}
|
1842 |
|
1843 |
+
inline void ggml_cuda_op_diag_mask_inf(
|
1844 |
+
const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst, char * src0_ddq_i,
|
1845 |
+
float * src0_ddf_i, float * src1_ddf_i, float * dst_ddf_i, int64_t i02, int64_t i01_low, int64_t i01_high, int i1,
|
1846 |
+
cudaStream_t & cudaStream_main){
|
1847 |
+
|
1848 |
+
GGML_ASSERT(src0_ddf_i != nullptr);
|
1849 |
+
GGML_ASSERT(dst_ddf_i != nullptr);
|
1850 |
+
|
1851 |
+
const int64_t ne00 = src0->ne[0];
|
1852 |
+
const int64_t ne01 = src0->ne[1];
|
1853 |
+
const int64_t i01_diff = i01_high - i01_low;
|
1854 |
+
|
1855 |
+
const int n_past = ((int32_t *) src1->data)[0];
|
1856 |
+
|
1857 |
+
// compute
|
1858 |
+
diag_mask_inf_f32_cuda(src0_ddf_i, dst_ddf_i, ne00, i01_diff, ne01, n_past, cudaStream_main);
|
1859 |
+
CUDA_CHECK(cudaGetLastError());
|
1860 |
+
|
1861 |
+
(void) dst;
|
1862 |
+
(void) src0_ddq_i;
|
1863 |
+
(void) src1_ddf_i;
|
1864 |
+
(void) i02;
|
1865 |
+
(void) i1;
|
1866 |
+
}
|
1867 |
+
|
1868 |
+
inline void ggml_cuda_op_soft_max(
|
1869 |
+
const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst, char * src0_ddq_i,
|
1870 |
+
float * src0_ddf_i, float * src1_ddf_i, float * dst_ddf_i, int64_t i02, int64_t i01_low, int64_t i01_high, int i1,
|
1871 |
+
cudaStream_t & cudaStream_main){
|
1872 |
+
|
1873 |
+
GGML_ASSERT(src0_ddf_i != nullptr);
|
1874 |
+
GGML_ASSERT(dst_ddf_i != nullptr);
|
1875 |
+
|
1876 |
+
const int64_t ne00 = src0->ne[0];
|
1877 |
+
const int64_t i01_diff = i01_high - i01_low;
|
1878 |
+
|
1879 |
+
// compute
|
1880 |
+
soft_max_f32_cuda(src0_ddf_i, dst_ddf_i, ne00, i01_diff, cudaStream_main);
|
1881 |
+
CUDA_CHECK(cudaGetLastError());
|
1882 |
+
|
1883 |
+
(void) src1;
|
1884 |
+
(void) dst;
|
1885 |
+
(void) src0_ddq_i;
|
1886 |
+
(void) src1_ddf_i;
|
1887 |
+
(void) i02;
|
1888 |
+
(void) i1;
|
1889 |
+
}
|
1890 |
+
|
1891 |
+
inline void ggml_cuda_op_scale(
|
1892 |
+
const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst, char * src0_ddq_i,
|
1893 |
+
float * src0_ddf_i, float * src1_ddf_i, float * dst_ddf_i, int64_t i02, int64_t i01_low, int64_t i01_high, int i1,
|
1894 |
+
cudaStream_t & cudaStream_main){
|
1895 |
+
|
1896 |
+
GGML_ASSERT(src0_ddf_i != nullptr);
|
1897 |
+
GGML_ASSERT(dst_ddf_i != nullptr);
|
1898 |
+
|
1899 |
+
const float scale = ((float *) src1->data)[0];
|
1900 |
+
|
1901 |
+
const int64_t ne00 = src0->ne[0];
|
1902 |
+
const int64_t i01_diff = i01_high - i01_low;
|
1903 |
+
|
1904 |
+
// compute
|
1905 |
+
scale_f32_cuda(src0_ddf_i, dst_ddf_i, scale, ne00*i01_diff, cudaStream_main);
|
1906 |
+
CUDA_CHECK(cudaGetLastError());
|
1907 |
+
|
1908 |
+
(void) src1;
|
1909 |
+
(void) dst;
|
1910 |
+
(void) src0_ddq_i;
|
1911 |
+
(void) src1_ddf_i;
|
1912 |
+
(void) i02;
|
1913 |
+
(void) i1;
|
1914 |
+
}
|
1915 |
+
|
1916 |
static void ggml_cuda_op(const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst,
|
1917 |
+
ggml_cuda_op_t op, bool src0_needs_f32, bool flatten_rows) {
|
1918 |
const int64_t ne00 = src0->ne[0];
|
1919 |
const int64_t ne01 = src0->ne[1];
|
1920 |
const int64_t ne02 = src0->ne[2];
|
|
|
1937 |
GGML_ASSERT(!use_src1 || src1->backend != GGML_BACKEND_GPU_SPLIT);
|
1938 |
|
1939 |
// strides for iteration over dims 3 and 2
|
1940 |
+
const int64_t num_iters = flatten_rows ? 1 : ne02 * ne03;
|
1941 |
+
const int64_t stride_mod = flatten_rows ? ne02 * ne03 : 1;
|
1942 |
+
const int64_t src0_stride = ne00 * ne01 * stride_mod;
|
1943 |
+
const int64_t src1_stride = ne10 * ne11 * stride_mod;
|
1944 |
+
const int64_t dst_stride = ne0 * ne1 * stride_mod;
|
1945 |
|
1946 |
const size_t src0_ts = ggml_type_size(src0->type);
|
1947 |
const size_t src0_bs = ggml_blck_size(src0->type);
|
1948 |
|
1949 |
+
struct ggml_tensor_extra_gpu * src0_extra = (ggml_tensor_extra_gpu *) src0->extra;
|
1950 |
struct ggml_tensor_extra_gpu * src1_extra = use_src1 ? (ggml_tensor_extra_gpu *) src1->extra : nullptr;
|
1951 |
+
struct ggml_tensor_extra_gpu * dst_extra = (ggml_tensor_extra_gpu *) dst->extra;
|
1952 |
|
1953 |
const bool src0_on_device = src0->backend == GGML_BACKEND_GPU || src0->backend == GGML_BACKEND_GPU_SPLIT;
|
1954 |
+
const bool src0_is_contiguous = ggml_is_contiguous(src0);
|
1955 |
const bool src0_is_f32 = src0->type == GGML_TYPE_F32;
|
1956 |
|
1957 |
+
const bool src1_is_contiguous = use_src1 && ggml_is_contiguous(src1);
|
1958 |
+
const bool src1_stays_on_host = use_src1 && (
|
1959 |
+
dst->op == GGML_OP_SCALE || dst->op == GGML_OP_DIAG_MASK_INF || dst->op == GGML_OP_ROPE);
|
1960 |
+
|
1961 |
const bool split = src0->backend == GGML_BACKEND_GPU_SPLIT;
|
1962 |
|
1963 |
const to_fp32_cuda_t to_fp32_cuda = ggml_get_to_fp32_cuda(src0->type);
|
|
|
1966 |
char * src0_ddq[GGML_CUDA_MAX_DEVICES] = {nullptr}; // quantized
|
1967 |
float * src0_ddf[GGML_CUDA_MAX_DEVICES] = {nullptr}; // float
|
1968 |
float * src1_ddf[GGML_CUDA_MAX_DEVICES] = {nullptr};
|
1969 |
+
float * dst_ddf[GGML_CUDA_MAX_DEVICES] = {nullptr};
|
1970 |
|
1971 |
// asq = actual size quantized, asf = actual size float
|
1972 |
size_t src0_asq[GGML_CUDA_MAX_DEVICES] = {0};
|
1973 |
size_t src0_asf[GGML_CUDA_MAX_DEVICES] = {0};
|
1974 |
size_t src1_asf[GGML_CUDA_MAX_DEVICES] = {0};
|
1975 |
+
size_t dst_asf[GGML_CUDA_MAX_DEVICES] = {0};
|
1976 |
|
1977 |
for (int id = 0; id < g_device_count; ++id) {
|
1978 |
if (!split && id != g_main_device) {
|
|
|
1985 |
int64_t row_low, row_high;
|
1986 |
if (split) {
|
1987 |
row_low = id == 0 ? 0 : nrows0*g_tensor_split[id];
|
|
|
1988 |
row_high = id == g_device_count - 1 ? nrows0 : nrows0*g_tensor_split[id + 1];
|
|
|
1989 |
} else {
|
1990 |
row_low = 0;
|
1991 |
row_high = nrows0;
|
|
|
1998 |
|
1999 |
cudaSetDevice(id);
|
2000 |
|
2001 |
+
if (src0_on_device && src0_is_contiguous) {
|
2002 |
if (src0_is_f32) {
|
2003 |
src0_ddf[id] = (float *) src0_extra->data_device[id];
|
2004 |
} else {
|
|
|
2016 |
src0_ddf[id] = (float *) ggml_cuda_pool_malloc(row_diff*ne00 * sizeof(float), &src0_asf[id]);
|
2017 |
}
|
2018 |
|
2019 |
+
if (use_src1 && !src1_stays_on_host) {
|
2020 |
+
if (src1_on_device && src1_is_contiguous) {
|
2021 |
src1_ddf[id] = (float *) src1_extra->data_device[id];
|
2022 |
} else {
|
2023 |
src1_ddf[id] = (float *) ggml_cuda_pool_malloc(num_iters*src1_stride * sizeof(float), &src1_asf[id]);
|
|
|
2030 |
dst_ddf[id] = (float *) ggml_cuda_pool_malloc(size_dst_ddf, &dst_asf[id]);
|
2031 |
}
|
2032 |
|
2033 |
+
const int64_t i03_max = flatten_rows ? 1 : ne03;
|
2034 |
+
const int64_t i02_max = flatten_rows ? 1 : ne02;
|
2035 |
+
const int64_t rows_per_iter = flatten_rows ? nrows0 : ne01;
|
2036 |
+
|
2037 |
+
for (int64_t i03 = 0; i03 < i03_max; i03++) {
|
2038 |
const int64_t i13 = i03 % ne13;
|
2039 |
+
for (int64_t i02 = 0; i02 < i02_max; i02++) {
|
2040 |
const int64_t i12 = i02 % ne12;
|
2041 |
|
2042 |
const int64_t i0 = i03*ne02 + i02;
|
2043 |
+
|
2044 |
+
// i0 values that contain the lower/upper rows for a split tensor when using multiple GPUs
|
2045 |
+
const int64_t i0_offset_low = row_low/rows_per_iter;
|
2046 |
+
const int64_t i0_offset_high = row_high/rows_per_iter;
|
2047 |
|
2048 |
int64_t i01_low = 0;
|
2049 |
+
int64_t i01_high = rows_per_iter;
|
2050 |
if (split) {
|
2051 |
if (i0 < i0_offset_low || i0 > i0_offset_high) {
|
2052 |
continue;
|
2053 |
}
|
2054 |
if (i0 == i0_offset_low) {
|
2055 |
+
i01_low = row_low % rows_per_iter;
|
2056 |
}
|
2057 |
if (i0 == i0_offset_high) {
|
2058 |
+
i01_high = row_high % rows_per_iter;
|
2059 |
}
|
2060 |
}
|
2061 |
|
|
|
2064 |
// Removing both asserts results in i01_high becoming 0 which in turn results in garbage output.
|
2065 |
// The root cause seems to be a problem with i0_offset_high becoming 0 when it should always be >0 (for single GPU).
|
2066 |
GGML_ASSERT(i01_low == 0 || g_device_count > 1);
|
2067 |
+
GGML_ASSERT(i01_high == rows_per_iter || g_device_count > 1);
|
2068 |
|
2069 |
const int64_t i01_diff = i01_high - i01_low;
|
2070 |
if (i01_diff == 0) {
|
|
|
2072 |
}
|
2073 |
const int64_t i11 = i13*ne12 + i12;
|
2074 |
|
2075 |
+
cudaStream_t cudaStream_main = g_cudaStreams_main[id][i0 % GGML_CUDA_MAX_STREAMS];
|
2076 |
cudaStream_t cudaStream_memcpy_src1 = g_cudaStreams_memcpy_src1[id][i0 % GGML_CUDA_MAX_STREAMS];
|
2077 |
+
cudaEvent_t cudaEvent_memcpy_src1 = g_cudaEvents_memcpy_src1[id][i0 % GGML_CUDA_MAX_EVENTS];
|
2078 |
|
2079 |
// for split tensors the data begins at i0 == i0_offset_low
|
2080 |
char * src0_ddq_i = src0_ddq[id] + (i0 - i0_offset_low)*src0_stride*src0_ts/src0_bs;
|
2081 |
float * src0_ddf_i = src0_ddf[id] + (i0 - i0_offset_low)*src0_stride;
|
2082 |
float * src1_ddf_i = src1_ddf[id] + i11*src1_stride;
|
2083 |
+
float * dst_ddf_i = dst_ddf[id] + (i0 - i0_offset_low)*dst_stride;
|
2084 |
|
2085 |
// for split tensors the data pointer needs to be rounded down
|
2086 |
// to the bin edge for i03, i02 bins beyond the first
|
2087 |
if (i0 - i0_offset_low > 0) {
|
2088 |
+
GGML_ASSERT(!flatten_rows);
|
2089 |
src0_ddq_i -= (row_low % ne01)*ne00 * src0_ts/src0_bs;
|
2090 |
src0_ddf_i -= (row_low % ne01)*ne00;
|
2091 |
+
dst_ddf_i -= (row_low % ne0)*ne1;
|
|
|
|
|
2092 |
}
|
2093 |
|
2094 |
// the main device memory buffer can be on VRAM scratch, with space for all partial results
|
|
|
2098 |
}
|
2099 |
|
2100 |
// copy src0, src1 to device if necessary
|
2101 |
+
if (use_src1 && !src1_stays_on_host) {
|
2102 |
if (src1->backend == GGML_BACKEND_CPU) {
|
2103 |
+
GGML_ASSERT(!flatten_rows || nrows0 == ggml_nrows(src1));
|
2104 |
+
int64_t nrows1 = flatten_rows ? nrows0 : ne11;
|
2105 |
+
CUDA_CHECK(ggml_cuda_cpy_tensor_2d(src1_ddf_i, src1, i03, i02, 0, nrows1, cudaStream_memcpy_src1));
|
2106 |
+
} else if (src1->backend == GGML_BACKEND_GPU && src1_is_contiguous) {
|
2107 |
if (id != g_main_device) {
|
2108 |
+
GGML_ASSERT(!flatten_rows);
|
2109 |
float * src1_ddf_i_source = (float *) src1_extra->data_device[g_main_device];
|
2110 |
src1_ddf_i_source += i11*src1_stride;
|
2111 |
CUDA_CHECK(cudaMemcpyAsync(src1_ddf_i, src1_ddf_i_source, src1_stride*sizeof(float),
|
2112 |
cudaMemcpyDeviceToDevice, cudaStream_memcpy_src1));
|
2113 |
}
|
2114 |
+
} else if (src1_on_device && !src1_is_contiguous) {
|
2115 |
+
GGML_ASSERT(!split);
|
2116 |
+
CUDA_CHECK(ggml_cuda_cpy_tensor_2d(src1_ddf_i, src1, i03, i02, 0, ne11, cudaStream_main));
|
2117 |
} else {
|
2118 |
GGML_ASSERT(false);
|
2119 |
}
|
2120 |
}
|
2121 |
CUDA_CHECK(cudaEventRecord(cudaEvent_memcpy_src1, cudaStream_memcpy_src1));
|
2122 |
+
|
2123 |
+
if (!src0_on_device || !src0_is_contiguous) {
|
2124 |
if (src0_is_f32) {
|
2125 |
+
CUDA_CHECK(ggml_cuda_cpy_tensor_2d(src0_ddf_i, src0, i03, i02, i01_low, i01_high, cudaStream_main));
|
2126 |
} else {
|
2127 |
+
CUDA_CHECK(ggml_cuda_cpy_tensor_2d(src0_ddq_i, src0, i03, i02, i01_low, i01_high, cudaStream_main));
|
2128 |
}
|
2129 |
}
|
2130 |
|
2131 |
+
// convert src0 to f32 if it is necessary for the ggml_cuda_op
|
2132 |
if (src0_needs_f32 && !src0_is_f32) {
|
2133 |
to_fp32_cuda(src0_ddq_i, src0_ddf_i, i01_diff*ne00, cudaStream_main);
|
2134 |
CUDA_CHECK(cudaGetLastError());
|
|
|
2193 |
|
2194 |
void ggml_cuda_add(const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
|
2195 |
GGML_ASSERT(src0->type == GGML_TYPE_F32 && src1->type == GGML_TYPE_F32 && dst->type == GGML_TYPE_F32);
|
2196 |
+
ggml_cuda_op(src0, src1, dst, ggml_cuda_op_add, true, true);
|
2197 |
}
|
2198 |
|
2199 |
void ggml_cuda_mul(const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
|
2200 |
GGML_ASSERT(src0->type == GGML_TYPE_F32 && src1->type == GGML_TYPE_F32 && dst->type == GGML_TYPE_F32);
|
2201 |
+
ggml_cuda_op(src0, src1, dst, ggml_cuda_op_mul, true, false); // TODO ggml_cuda_op needs modification for flatten
|
2202 |
}
|
2203 |
|
2204 |
void ggml_cuda_silu(const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
|
2205 |
GGML_ASSERT(src0->type == GGML_TYPE_F32 && dst->type == GGML_TYPE_F32);
|
2206 |
+
ggml_cuda_op(src0, src1, dst, ggml_cuda_op_silu, true, true);
|
2207 |
}
|
2208 |
|
2209 |
void ggml_cuda_rms_norm(const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
|
2210 |
GGML_ASSERT(src0->type == GGML_TYPE_F32 && dst->type == GGML_TYPE_F32);
|
2211 |
+
ggml_cuda_op(src0, src1, dst, ggml_cuda_op_rms_norm, true, true);
|
2212 |
}
|
2213 |
|
2214 |
bool ggml_cuda_can_mul_mat(const struct ggml_tensor * src0, const struct ggml_tensor * src1, struct ggml_tensor * dst) {
|
|
|
2215 |
const int64_t ne10 = src1->ne[0];
|
2216 |
|
2217 |
const int64_t ne0 = dst->ne[0];
|
2218 |
const int64_t ne1 = dst->ne[1];
|
2219 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2220 |
// TODO: find the optimal values for these
|
2221 |
if ((src0->type == GGML_TYPE_F32 || src0->type == GGML_TYPE_F16 || ggml_is_quantized(src0->type)) &&
|
2222 |
src1->type == GGML_TYPE_F32 &&
|
|
|
2228 |
return false;
|
2229 |
}
|
2230 |
|
2231 |
+
void ggml_cuda_mul_mat_vec_p021(const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst){
|
2232 |
+
GGML_ASSERT(ggml_is_permuted(src0) && ggml_is_permuted(src1));
|
2233 |
+
GGML_ASSERT(src0->backend != GGML_BACKEND_GPU_SPLIT);
|
2234 |
+
GGML_ASSERT(src0->nb[0] <= src0->nb[1] && src0->nb[2] <= src0->nb[3]); // 0213 permutation
|
2235 |
+
GGML_ASSERT(src1->nb[0] <= src1->nb[1] && src1->nb[2] <= src1->nb[3]); // 0213 permutation
|
2236 |
+
GGML_ASSERT(src0->type == GGML_TYPE_F16);
|
2237 |
+
GGML_ASSERT(src1->type == GGML_TYPE_F32);
|
2238 |
+
|
2239 |
+
const int64_t ne00 = src0->ne[0];
|
2240 |
+
const int64_t ne01 = src0->ne[1];
|
2241 |
+
const int64_t ne02 = src0->ne[2];
|
2242 |
+
|
2243 |
+
CUDA_CHECK(cudaSetDevice(g_main_device));
|
2244 |
+
cudaStream_t cudaStream_main = g_cudaStreams_main[g_main_device][0];
|
2245 |
+
|
2246 |
+
struct ggml_tensor_extra_gpu * src0_extra = (ggml_tensor_extra_gpu *) src0->extra;
|
2247 |
+
void * src0_ddq = src0_extra->data_device[g_main_device];
|
2248 |
+
|
2249 |
+
struct ggml_tensor_extra_gpu * src1_extra = (ggml_tensor_extra_gpu *) src1->extra;
|
2250 |
+
float * src1_ddf = (float *) src1_extra->data_device[g_main_device];
|
2251 |
+
|
2252 |
+
struct ggml_tensor_extra_gpu * dst_extra = (ggml_tensor_extra_gpu *) dst->extra;
|
2253 |
+
float * dst_ddf = (float *) dst_extra->data_device[g_main_device];
|
2254 |
+
|
2255 |
+
ggml_mul_mat_p021_f16_f32_cuda(src0_ddq, src1_ddf, dst_ddf, ne00, ne01, ne02, cudaStream_main);
|
2256 |
+
|
2257 |
+
CUDA_CHECK(cudaDeviceSynchronize());
|
2258 |
+
}
|
2259 |
+
|
2260 |
+
void ggml_cuda_mul_mat_vec_nc(const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst){
|
2261 |
+
GGML_ASSERT(!ggml_is_contiguous(src0) && ggml_is_contiguous(src1));
|
2262 |
+
GGML_ASSERT(!ggml_is_permuted(src0));
|
2263 |
+
GGML_ASSERT(src0->backend != GGML_BACKEND_GPU_SPLIT);
|
2264 |
+
GGML_ASSERT(src0->type == GGML_TYPE_F16);
|
2265 |
+
GGML_ASSERT(src1->type == GGML_TYPE_F32);
|
2266 |
+
|
2267 |
+
const int64_t ne00 = src0->ne[0];
|
2268 |
+
const int64_t ne01 = src0->ne[1];
|
2269 |
+
const int64_t ne02 = src0->ne[2];
|
2270 |
+
|
2271 |
+
const int64_t nb01 = src0->nb[1];
|
2272 |
+
const int64_t nb02 = src0->nb[2];
|
2273 |
+
|
2274 |
+
CUDA_CHECK(cudaSetDevice(g_main_device));
|
2275 |
+
cudaStream_t cudaStream_main = g_cudaStreams_main[g_main_device][0];
|
2276 |
+
|
2277 |
+
struct ggml_tensor_extra_gpu * src0_extra = (ggml_tensor_extra_gpu *) src0->extra;
|
2278 |
+
void * src0_ddq = src0_extra->data_device[g_main_device];
|
2279 |
+
|
2280 |
+
struct ggml_tensor_extra_gpu * src1_extra = (ggml_tensor_extra_gpu *) src1->extra;
|
2281 |
+
float * src1_ddf = (float *) src1_extra->data_device[g_main_device];
|
2282 |
+
|
2283 |
+
struct ggml_tensor_extra_gpu * dst_extra = (ggml_tensor_extra_gpu *) dst->extra;
|
2284 |
+
float * dst_ddf = (float *) dst_extra->data_device[g_main_device];
|
2285 |
+
|
2286 |
+
const int row_stride_x = nb01 / sizeof(half);
|
2287 |
+
const int channel_stride_x = nb02 / sizeof(half);
|
2288 |
+
|
2289 |
+
ggml_mul_mat_vec_nc_f16_f32_cuda(src0_ddq, src1_ddf, dst_ddf, ne00, ne01, row_stride_x, ne02, channel_stride_x, cudaStream_main);
|
2290 |
+
|
2291 |
+
CUDA_CHECK(cudaDeviceSynchronize());
|
2292 |
+
}
|
2293 |
+
|
2294 |
void ggml_cuda_mul_mat(const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
|
2295 |
+
bool all_on_device = (src0->backend == GGML_BACKEND_GPU || src0->backend == GGML_BACKEND_GPU_SPLIT) &&
|
2296 |
+
src1->backend == GGML_BACKEND_GPU && dst->backend == GGML_BACKEND_GPU;
|
2297 |
+
|
2298 |
+
if (all_on_device && ggml_is_permuted(src0) && ggml_is_permuted(src1) && src1->ne[1] == 1) {
|
2299 |
+
ggml_cuda_mul_mat_vec_p021(src0, src1, dst);
|
2300 |
+
} else if (all_on_device && !ggml_is_contiguous(src0) && ggml_is_contiguous(src1) && src1->ne[1] == 1) {
|
2301 |
+
ggml_cuda_mul_mat_vec_nc(src0, src1, dst);
|
2302 |
+
}else if (src0->type == GGML_TYPE_F32) {
|
2303 |
+
ggml_cuda_op(src0, src1, dst, ggml_cuda_op_mul_mat_cublas, true, false);
|
2304 |
} else if (ggml_is_quantized(src0->type) || src0->type == GGML_TYPE_F16) {
|
2305 |
+
if (src1->ne[1] == 1 && src0->ne[0] % GGML_CUDA_DMMV_X == 0 && src0->ne[1] % GGML_CUDA_DMMV_Y == 0) {
|
2306 |
+
ggml_cuda_op(src0, src1, dst, ggml_cuda_op_dequantize_mul_mat_vec, false, false);
|
2307 |
} else {
|
2308 |
+
ggml_cuda_op(src0, src1, dst, ggml_cuda_op_mul_mat_cublas, true, false);
|
2309 |
}
|
2310 |
} else {
|
2311 |
GGML_ASSERT(false);
|
2312 |
}
|
2313 |
}
|
2314 |
|
2315 |
+
void ggml_cuda_scale(const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
|
2316 |
+
GGML_ASSERT(src0->type == GGML_TYPE_F32 && dst->type == GGML_TYPE_F32);
|
2317 |
+
ggml_cuda_op(src0, src1, dst, ggml_cuda_op_scale, true, true);
|
2318 |
+
}
|
2319 |
+
|
2320 |
+
void ggml_cuda_cpy(const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
|
2321 |
+
const int64_t ne = ggml_nelements(src0);
|
2322 |
+
GGML_ASSERT(ne == ggml_nelements(src1));
|
2323 |
+
|
2324 |
+
GGML_ASSERT(src0->backend == GGML_BACKEND_GPU);
|
2325 |
+
GGML_ASSERT(src1->backend == GGML_BACKEND_GPU);
|
2326 |
+
|
2327 |
+
GGML_ASSERT(ggml_nbytes(src0) <= INT_MAX);
|
2328 |
+
GGML_ASSERT(ggml_nbytes(src1) <= INT_MAX);
|
2329 |
+
|
2330 |
+
const int64_t ne00 = src0->ne[0];
|
2331 |
+
const int64_t ne01 = src0->ne[1];
|
2332 |
+
GGML_ASSERT(src0->ne[3] == 1);
|
2333 |
+
|
2334 |
+
const int64_t nb00 = src0->nb[0];
|
2335 |
+
const int64_t nb01 = src0->nb[1];
|
2336 |
+
const int64_t nb02 = src0->nb[2];
|
2337 |
+
|
2338 |
+
const int64_t ne10 = src1->ne[0];
|
2339 |
+
const int64_t ne11 = src1->ne[1];
|
2340 |
+
GGML_ASSERT(src1->ne[3] == 1);
|
2341 |
+
|
2342 |
+
const int64_t nb10 = src1->nb[0];
|
2343 |
+
const int64_t nb11 = src1->nb[1];
|
2344 |
+
const int64_t nb12 = src1->nb[2];
|
2345 |
+
|
2346 |
+
CUDA_CHECK(cudaSetDevice(g_main_device));
|
2347 |
+
cudaStream_t cudaStream_main = g_cudaStreams_main[g_main_device][0];
|
2348 |
+
|
2349 |
+
const struct ggml_tensor_extra_gpu * src0_extra = (ggml_tensor_extra_gpu *) src0->extra;
|
2350 |
+
const struct ggml_tensor_extra_gpu * src1_extra = (ggml_tensor_extra_gpu *) src1->extra;
|
2351 |
+
|
2352 |
+
char * src0_ddc = (char *) src0_extra->data_device[g_main_device];
|
2353 |
+
char * src1_ddc = (char *) src1_extra->data_device[g_main_device];
|
2354 |
+
|
2355 |
+
if (src0->type == GGML_TYPE_F32 && src1->type == GGML_TYPE_F32) {
|
2356 |
+
ggml_cpy_f32_f32_cuda(src0_ddc, src1_ddc, ne, ne00, ne01, nb00, nb01, nb02,
|
2357 |
+
ne10, ne11, nb10, nb11, nb12, cudaStream_main);
|
2358 |
+
} else if (src0->type == GGML_TYPE_F32 && src1->type == GGML_TYPE_F16) {
|
2359 |
+
ggml_cpy_f32_f16_cuda(src0_ddc, src1_ddc, ne, ne00, ne01, nb00, nb01, nb02,
|
2360 |
+
ne10, ne11, nb10, nb11, nb12, cudaStream_main);
|
2361 |
+
} else {
|
2362 |
+
GGML_ASSERT(false);
|
2363 |
+
}
|
2364 |
+
|
2365 |
+
CUDA_CHECK(cudaDeviceSynchronize());
|
2366 |
+
|
2367 |
+
(void) dst;
|
2368 |
+
}
|
2369 |
+
|
2370 |
+
void ggml_cuda_diag_mask_inf(const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
|
2371 |
+
GGML_ASSERT(src0->type == GGML_TYPE_F32 && dst->type == GGML_TYPE_F32);
|
2372 |
+
ggml_cuda_op(src0, src1, dst, ggml_cuda_op_diag_mask_inf, true, true);
|
2373 |
+
}
|
2374 |
+
|
2375 |
+
void ggml_cuda_soft_max(const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
|
2376 |
+
GGML_ASSERT(src0->type == GGML_TYPE_F32 && dst->type == GGML_TYPE_F32);
|
2377 |
+
ggml_cuda_op(src0, src1, dst, ggml_cuda_op_soft_max, true, true);
|
2378 |
+
}
|
2379 |
+
|
2380 |
void ggml_cuda_rope(const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
|
2381 |
GGML_ASSERT(src0->type == GGML_TYPE_F32 && dst->type == GGML_TYPE_F32);
|
2382 |
+
ggml_cuda_op(src0, src1, dst, ggml_cuda_op_rope, true, false); // FIXME flatten changes results
|
2383 |
}
|
2384 |
|
2385 |
void ggml_cuda_nop(const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
|
|
|
2393 |
const size_t nb1 = tensor->nb[1];
|
2394 |
ggml_backend backend = tensor->backend;
|
2395 |
struct ggml_tensor_extra_gpu * extra = new struct ggml_tensor_extra_gpu;
|
2396 |
+
memset(extra, 0, sizeof(*extra));
|
2397 |
|
2398 |
for (int id = 0; id < g_device_count; ++id) {
|
|
|
|
|
2399 |
if (backend == GGML_BACKEND_GPU && id != g_main_device) {
|
2400 |
continue;
|
2401 |
}
|
|
|
2408 |
row_high = nrows;
|
2409 |
} else if (backend == GGML_BACKEND_GPU_SPLIT) {
|
2410 |
row_low = id == 0 ? 0 : nrows*g_tensor_split[id];
|
|
|
2411 |
row_high = id == g_device_count - 1 ? nrows : nrows*g_tensor_split[id + 1];
|
|
|
|
|
2412 |
} else {
|
2413 |
GGML_ASSERT(false);
|
2414 |
}
|
|
|
2452 |
delete extra;
|
2453 |
}
|
2454 |
|
2455 |
+
void ggml_cuda_assign_buffers_impl(struct ggml_tensor * tensor, bool scratch) {
|
2456 |
+
if (scratch && g_scratch_size == 0) {
|
2457 |
+
return;
|
2458 |
}
|
2459 |
|
2460 |
+
// recursively assign CUDA buffers until a compute tensor is found
|
2461 |
+
if (tensor->src0 != nullptr && tensor->src0->backend == GGML_BACKEND_CPU) {
|
2462 |
+
const ggml_op src0_op = tensor->src0->op;
|
2463 |
+
if (src0_op == GGML_OP_RESHAPE || src0_op == GGML_OP_TRANSPOSE || src0_op == GGML_OP_VIEW) {
|
2464 |
+
ggml_cuda_assign_buffers_impl(tensor->src0, scratch);
|
2465 |
+
}
|
2466 |
+
}
|
2467 |
+
if (tensor->op == GGML_OP_CPY && tensor->src1->backend == GGML_BACKEND_CPU) {
|
2468 |
+
ggml_cuda_assign_buffers_impl(tensor->src1, scratch);
|
2469 |
}
|
2470 |
|
2471 |
tensor->backend = GGML_BACKEND_GPU;
|
2472 |
struct ggml_tensor_extra_gpu * extra = new ggml_tensor_extra_gpu;
|
2473 |
|
2474 |
+
const bool inplace = (tensor->src0 != nullptr && tensor->src0->data == tensor->data) ||
|
2475 |
+
tensor->op == GGML_OP_VIEW;
|
2476 |
+
const size_t size = ggml_nbytes(tensor);
|
2477 |
|
2478 |
CUDA_CHECK(cudaSetDevice(g_main_device));
|
2479 |
if (inplace && tensor->src0->backend == GGML_BACKEND_GPU) {
|
2480 |
struct ggml_tensor_extra_gpu * src0_extra = (ggml_tensor_extra_gpu * ) tensor->src0->extra;
|
2481 |
+
char * src0_ddc = (char *) src0_extra->data_device[g_main_device];
|
2482 |
+
size_t offset = 0;
|
2483 |
+
if (tensor->op == GGML_OP_VIEW) {
|
2484 |
+
memcpy(&offset, tensor->opt[0]->data, sizeof(size_t));
|
2485 |
+
}
|
2486 |
+
extra->data_device[g_main_device] = src0_ddc + offset;
|
2487 |
+
} else if (tensor->op == GGML_OP_CPY) {
|
2488 |
+
struct ggml_tensor_extra_gpu * src1_extra = (ggml_tensor_extra_gpu * ) tensor->src1->extra;
|
2489 |
+
void * src1_ddv = src1_extra->data_device[g_main_device];
|
2490 |
+
extra->data_device[g_main_device] = src1_ddv;
|
2491 |
+
} else if (scratch) {
|
2492 |
+
GGML_ASSERT(size <= g_scratch_size);
|
2493 |
+
if (g_scratch_offset + size > g_scratch_size) {
|
2494 |
+
g_scratch_offset = 0;
|
2495 |
+
}
|
2496 |
+
|
2497 |
char * data = (char *) g_scratch_buffer;
|
2498 |
if (data == nullptr) {
|
2499 |
CUDA_CHECK(cudaMalloc(&data, g_scratch_size));
|
2500 |
g_scratch_buffer = data;
|
2501 |
}
|
2502 |
extra->data_device[g_main_device] = data + g_scratch_offset;
|
|
|
2503 |
|
2504 |
+
g_scratch_offset += size;
|
2505 |
+
|
2506 |
+
GGML_ASSERT(g_scratch_offset <= g_scratch_size);
|
2507 |
+
} else { // allocate new buffers outside of scratch
|
2508 |
+
void * data;
|
2509 |
+
CUDA_CHECK(cudaMalloc(&data, size));
|
2510 |
+
CUDA_CHECK(cudaMemset(data, 0, size));
|
2511 |
+
extra->data_device[g_main_device] = data;
|
2512 |
+
}
|
2513 |
|
|
|
2514 |
tensor->extra = extra;
|
2515 |
}
|
2516 |
|
2517 |
+
void ggml_cuda_assign_buffers(struct ggml_tensor * tensor) {
|
2518 |
+
ggml_cuda_assign_buffers_impl(tensor, true);
|
2519 |
+
}
|
2520 |
+
|
2521 |
+
void ggml_cuda_assign_buffers_no_scratch(struct ggml_tensor * tensor) {
|
2522 |
+
ggml_cuda_assign_buffers_impl(tensor, false);
|
2523 |
+
}
|
2524 |
+
|
2525 |
void ggml_cuda_set_main_device(int main_device) {
|
2526 |
+
if (main_device >= g_device_count) {
|
2527 |
fprintf(stderr, "warning: cannot set main_device=%d because there are only %d devices. Using device %d instead.\n",
|
2528 |
main_device, g_device_count, g_main_device);
|
2529 |
return;
|
|
|
2540 |
g_scratch_size = scratch_size;
|
2541 |
}
|
2542 |
|
2543 |
+
void ggml_cuda_free_scratch() {
|
2544 |
+
if (g_scratch_buffer == nullptr) {
|
2545 |
+
return;
|
2546 |
+
}
|
2547 |
+
|
2548 |
+
CUDA_CHECK(cudaFree(g_scratch_buffer));
|
2549 |
+
g_scratch_buffer = nullptr;
|
2550 |
+
}
|
2551 |
+
|
2552 |
bool ggml_cuda_compute_forward(struct ggml_compute_params * params, struct ggml_tensor * tensor){
|
2553 |
ggml_cuda_func_t func;
|
2554 |
const bool any_on_device = tensor->backend == GGML_BACKEND_GPU
|
|
|
2586 |
}
|
2587 |
func = ggml_cuda_mul_mat;
|
2588 |
break;
|
2589 |
+
case GGML_OP_SCALE:
|
2590 |
+
if (!any_on_device) {
|
2591 |
+
return false;
|
2592 |
+
}
|
2593 |
+
func = ggml_cuda_scale;
|
2594 |
+
break;
|
2595 |
+
case GGML_OP_CPY:
|
2596 |
+
if (!any_on_device) {
|
2597 |
+
return false;
|
2598 |
+
}
|
2599 |
+
func = ggml_cuda_cpy;
|
2600 |
+
break;
|
2601 |
case GGML_OP_RESHAPE:
|
2602 |
+
case GGML_OP_VIEW:
|
2603 |
+
case GGML_OP_PERMUTE:
|
2604 |
+
case GGML_OP_TRANSPOSE:
|
2605 |
if (!any_on_device) {
|
2606 |
return false;
|
2607 |
}
|
2608 |
func = ggml_cuda_nop;
|
2609 |
break;
|
2610 |
+
case GGML_OP_DIAG_MASK_INF:
|
2611 |
+
if (!any_on_device) {
|
2612 |
+
return false;
|
2613 |
+
}
|
2614 |
+
func = ggml_cuda_diag_mask_inf;
|
2615 |
+
break;
|
2616 |
+
case GGML_OP_SOFT_MAX:
|
2617 |
+
if (!any_on_device) {
|
2618 |
+
return false;
|
2619 |
+
}
|
2620 |
+
func = ggml_cuda_soft_max;
|
2621 |
+
break;
|
2622 |
case GGML_OP_ROPE:
|
2623 |
if (!any_on_device) {
|
2624 |
return false;
|
ggml-cuda.h
CHANGED
@@ -28,8 +28,10 @@ void ggml_cuda_transform_tensor(void * data, struct ggml_tensor * tensor);
|
|
28 |
|
29 |
void ggml_cuda_free_data(struct ggml_tensor * tensor);
|
30 |
void ggml_cuda_assign_buffers(struct ggml_tensor * tensor);
|
|
|
31 |
void ggml_cuda_set_main_device(int main_device);
|
32 |
void ggml_cuda_set_scratch_size(size_t scratch_size);
|
|
|
33 |
bool ggml_cuda_compute_forward(struct ggml_compute_params * params, struct ggml_tensor * tensor);
|
34 |
|
35 |
#ifdef __cplusplus
|
|
|
28 |
|
29 |
void ggml_cuda_free_data(struct ggml_tensor * tensor);
|
30 |
void ggml_cuda_assign_buffers(struct ggml_tensor * tensor);
|
31 |
+
void ggml_cuda_assign_buffers_no_scratch(struct ggml_tensor * tensor);
|
32 |
void ggml_cuda_set_main_device(int main_device);
|
33 |
void ggml_cuda_set_scratch_size(size_t scratch_size);
|
34 |
+
void ggml_cuda_free_scratch(void);
|
35 |
bool ggml_cuda_compute_forward(struct ggml_compute_params * params, struct ggml_tensor * tensor);
|
36 |
|
37 |
#ifdef __cplusplus
|
ggml-metal.h
CHANGED
@@ -55,6 +55,7 @@ void ggml_metal_set_tensor(struct ggml_metal_context * ctx, struct ggml_tensor *
|
|
55 |
void ggml_metal_get_tensor(struct ggml_metal_context * ctx, struct ggml_tensor * t);
|
56 |
|
57 |
// same as ggml_graph_compute but uses Metal
|
|
|
58 |
void ggml_metal_graph_compute(struct ggml_metal_context * ctx, struct ggml_cgraph * gf);
|
59 |
|
60 |
#ifdef __cplusplus
|
|
|
55 |
void ggml_metal_get_tensor(struct ggml_metal_context * ctx, struct ggml_tensor * t);
|
56 |
|
57 |
// same as ggml_graph_compute but uses Metal
|
58 |
+
// creates gf->n_threads command buffers in parallel
|
59 |
void ggml_metal_graph_compute(struct ggml_metal_context * ctx, struct ggml_cgraph * gf);
|
60 |
|
61 |
#ifdef __cplusplus
|
ggml-metal.m
CHANGED
@@ -57,6 +57,7 @@ struct ggml_metal_context {
|
|
57 |
GGML_METAL_DECL_KERNEL(get_rows_q5_k);
|
58 |
GGML_METAL_DECL_KERNEL(get_rows_q6_k);
|
59 |
GGML_METAL_DECL_KERNEL(rms_norm);
|
|
|
60 |
GGML_METAL_DECL_KERNEL(mul_mat_f16_f32);
|
61 |
GGML_METAL_DECL_KERNEL(mul_mat_q4_0_f32);
|
62 |
GGML_METAL_DECL_KERNEL(mul_mat_q4_1_f32);
|
@@ -66,8 +67,10 @@ struct ggml_metal_context {
|
|
66 |
GGML_METAL_DECL_KERNEL(mul_mat_q5_k_f32);
|
67 |
GGML_METAL_DECL_KERNEL(mul_mat_q6_k_f32);
|
68 |
GGML_METAL_DECL_KERNEL(rope);
|
|
|
69 |
GGML_METAL_DECL_KERNEL(cpy_f32_f16);
|
70 |
GGML_METAL_DECL_KERNEL(cpy_f32_f32);
|
|
|
71 |
|
72 |
#undef GGML_METAL_DECL_KERNEL
|
73 |
};
|
@@ -162,6 +165,7 @@ struct ggml_metal_context * ggml_metal_init(void) {
|
|
162 |
GGML_METAL_ADD_KERNEL(get_rows_q5_k);
|
163 |
GGML_METAL_ADD_KERNEL(get_rows_q6_k);
|
164 |
GGML_METAL_ADD_KERNEL(rms_norm);
|
|
|
165 |
GGML_METAL_ADD_KERNEL(mul_mat_f16_f32);
|
166 |
GGML_METAL_ADD_KERNEL(mul_mat_q4_0_f32);
|
167 |
GGML_METAL_ADD_KERNEL(mul_mat_q4_1_f32);
|
@@ -171,8 +175,10 @@ struct ggml_metal_context * ggml_metal_init(void) {
|
|
171 |
GGML_METAL_ADD_KERNEL(mul_mat_q5_k_f32);
|
172 |
GGML_METAL_ADD_KERNEL(mul_mat_q6_k_f32);
|
173 |
GGML_METAL_ADD_KERNEL(rope);
|
|
|
174 |
GGML_METAL_ADD_KERNEL(cpy_f32_f16);
|
175 |
GGML_METAL_ADD_KERNEL(cpy_f32_f32);
|
|
|
176 |
|
177 |
#undef GGML_METAL_ADD_KERNEL
|
178 |
}
|
@@ -284,528 +290,618 @@ void ggml_metal_get_tensor(
|
|
284 |
|
285 |
void ggml_metal_graph_compute(
|
286 |
struct ggml_metal_context * ctx,
|
287 |
-
|
288 |
metal_printf("%s: evaluating graph\n", __func__);
|
289 |
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
for (int i = 0; i <
|
298 |
-
|
299 |
-
|
300 |
-
struct ggml_tensor * src0 = gf->nodes[i]->src0;
|
301 |
-
struct ggml_tensor * src1 = gf->nodes[i]->src1;
|
302 |
-
struct ggml_tensor * dst = gf->nodes[i];
|
303 |
-
|
304 |
-
const int64_t ne00 = src0 ? src0->ne[0] : 0;
|
305 |
-
const int64_t ne01 = src0 ? src0->ne[1] : 0;
|
306 |
-
const int64_t ne02 = src0 ? src0->ne[2] : 0;
|
307 |
-
const int64_t ne03 = src0 ? src0->ne[3] : 0;
|
308 |
-
|
309 |
-
const uint64_t nb00 = src0 ? src0->nb[0] : 0;
|
310 |
-
const uint64_t nb01 = src0 ? src0->nb[1] : 0;
|
311 |
-
const uint64_t nb02 = src0 ? src0->nb[2] : 0;
|
312 |
-
const uint64_t nb03 = src0 ? src0->nb[3] : 0;
|
313 |
-
|
314 |
-
const int64_t ne10 = src1 ? src1->ne[0] : 0;
|
315 |
-
const int64_t ne11 = src1 ? src1->ne[1] : 0;
|
316 |
-
const int64_t ne12 = src1 ? src1->ne[2] : 0;
|
317 |
-
const int64_t ne13 = src1 ? src1->ne[3] : 0; UNUSED(ne13);
|
318 |
-
|
319 |
-
const uint64_t nb10 = src1 ? src1->nb[0] : 0;
|
320 |
-
const uint64_t nb11 = src1 ? src1->nb[1] : 0;
|
321 |
-
const uint64_t nb12 = src1 ? src1->nb[2] : 0;
|
322 |
-
const uint64_t nb13 = src1 ? src1->nb[3] : 0; UNUSED(nb13);
|
323 |
-
|
324 |
-
const int64_t ne0 = dst ? dst->ne[0] : 0;
|
325 |
-
const int64_t ne1 = dst ? dst->ne[1] : 0;
|
326 |
-
const int64_t ne2 = dst ? dst->ne[2] : 0;
|
327 |
-
const int64_t ne3 = dst ? dst->ne[3] : 0;
|
328 |
-
|
329 |
-
const uint64_t nb0 = dst ? dst->nb[0] : 0;
|
330 |
-
const uint64_t nb1 = dst ? dst->nb[1] : 0;
|
331 |
-
const uint64_t nb2 = dst ? dst->nb[2] : 0;
|
332 |
-
const uint64_t nb3 = dst ? dst->nb[3] : 0;
|
333 |
-
|
334 |
-
const enum ggml_type src0t = src0 ? src0->type : GGML_TYPE_COUNT;
|
335 |
-
const enum ggml_type src1t = src1 ? src1->type : GGML_TYPE_COUNT;
|
336 |
-
const enum ggml_type dstt = dst ? dst->type : GGML_TYPE_COUNT;
|
337 |
-
|
338 |
-
id<MTLBuffer> id_src0 = src0 ? ggml_metal_get_buffer(ctx, src0, &offs_src0) : nil;
|
339 |
-
id<MTLBuffer> id_src1 = src1 ? ggml_metal_get_buffer(ctx, src1, &offs_src1) : nil;
|
340 |
-
id<MTLBuffer> id_dst = dst ? ggml_metal_get_buffer(ctx, dst, &offs_dst) : nil;
|
341 |
-
|
342 |
-
//metal_printf("%s: op - %s\n", __func__, ggml_op_name(dst->op));
|
343 |
-
//if (src0) {
|
344 |
-
// metal_printf("%s: src0 - %4s [%5lld, %5lld, %5lld], %d, %s\n", __func__, ggml_type_name(src0t), ne00, ne01, ne02,
|
345 |
-
// ggml_is_contiguous(src0), src0->name);
|
346 |
-
//}
|
347 |
-
//if (src1) {
|
348 |
-
// metal_printf("%s: src1 - %4s [%5lld, %5lld, %5lld], %d, %s\n", __func__, ggml_type_name(src1t), ne10, ne11, ne12,
|
349 |
-
// ggml_is_contiguous(src1), src1->name);
|
350 |
-
//}
|
351 |
-
//if (dst) {
|
352 |
-
// metal_printf("%s: dst - %4s [%5lld, %5lld, %5lld], 1, %s\n", __func__, ggml_type_name(dstt), ne0, ne1, ne2,
|
353 |
-
// dst->name);
|
354 |
-
//}
|
355 |
-
|
356 |
-
switch (dst->op) {
|
357 |
-
case GGML_OP_RESHAPE:
|
358 |
-
case GGML_OP_VIEW:
|
359 |
-
case GGML_OP_TRANSPOSE:
|
360 |
-
case GGML_OP_PERMUTE:
|
361 |
-
{
|
362 |
-
// noop
|
363 |
-
} break;
|
364 |
-
case GGML_OP_ADD:
|
365 |
-
{
|
366 |
-
if (encoder == nil) {
|
367 |
-
encoder = [command_buffer computeCommandEncoder];
|
368 |
-
}
|
369 |
-
|
370 |
-
[encoder setComputePipelineState:ctx->pipeline_add];
|
371 |
-
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
|
372 |
-
[encoder setBuffer:id_src1 offset:offs_src1 atIndex:1];
|
373 |
-
[encoder setBuffer:id_dst offset:offs_dst atIndex:2];
|
374 |
-
|
375 |
-
const int64_t n = ggml_nelements(dst);
|
376 |
-
|
377 |
-
[encoder dispatchThreadgroups:MTLSizeMake(n, 1, 1) threadsPerThreadgroup:MTLSizeMake(1, 1, 1)];
|
378 |
-
} break;
|
379 |
-
case GGML_OP_MUL:
|
380 |
-
{
|
381 |
-
if (encoder == nil) {
|
382 |
-
encoder = [command_buffer computeCommandEncoder];
|
383 |
-
}
|
384 |
-
|
385 |
-
if (ggml_nelements(src1) == ne10) {
|
386 |
-
// src1 is a row
|
387 |
-
[encoder setComputePipelineState:ctx->pipeline_mul_row];
|
388 |
-
} else {
|
389 |
-
[encoder setComputePipelineState:ctx->pipeline_mul];
|
390 |
-
}
|
391 |
-
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
|
392 |
-
[encoder setBuffer:id_src1 offset:offs_src1 atIndex:1];
|
393 |
-
[encoder setBuffer:id_dst offset:offs_dst atIndex:2];
|
394 |
-
[encoder setBytes:&ne00 length:sizeof(ne00) atIndex:3];
|
395 |
-
|
396 |
-
const int64_t n = ggml_nelements(dst);
|
397 |
-
|
398 |
-
[encoder dispatchThreadgroups:MTLSizeMake(n, 1, 1) threadsPerThreadgroup:MTLSizeMake(1, 1, 1)];
|
399 |
-
} break;
|
400 |
-
case GGML_OP_SCALE:
|
401 |
-
{
|
402 |
-
if (encoder == nil) {
|
403 |
-
encoder = [command_buffer computeCommandEncoder];
|
404 |
-
}
|
405 |
-
|
406 |
-
const float scale = *(const float *) src1->data;
|
407 |
-
|
408 |
-
[encoder setComputePipelineState:ctx->pipeline_scale];
|
409 |
-
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
|
410 |
-
[encoder setBuffer:id_dst offset:offs_dst atIndex:1];
|
411 |
-
[encoder setBytes:&scale length:sizeof(scale) atIndex:2];
|
412 |
-
|
413 |
-
const int64_t n = ggml_nelements(dst);
|
414 |
-
|
415 |
-
[encoder dispatchThreadgroups:MTLSizeMake(n, 1, 1) threadsPerThreadgroup:MTLSizeMake(1, 1, 1)];
|
416 |
-
} break;
|
417 |
-
case GGML_OP_SILU:
|
418 |
-
{
|
419 |
-
if (encoder == nil) {
|
420 |
-
encoder = [command_buffer computeCommandEncoder];
|
421 |
-
}
|
422 |
-
|
423 |
-
[encoder setComputePipelineState:ctx->pipeline_silu];
|
424 |
-
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
|
425 |
-
[encoder setBuffer:id_dst offset:offs_dst atIndex:1];
|
426 |
-
|
427 |
-
const int64_t n = ggml_nelements(dst);
|
428 |
-
|
429 |
-
[encoder dispatchThreadgroups:MTLSizeMake(n, 1, 1) threadsPerThreadgroup:MTLSizeMake(1, 1, 1)];
|
430 |
-
} break;
|
431 |
-
case GGML_OP_RELU:
|
432 |
-
{
|
433 |
-
if (encoder == nil) {
|
434 |
-
encoder = [command_buffer computeCommandEncoder];
|
435 |
-
}
|
436 |
-
|
437 |
-
[encoder setComputePipelineState:ctx->pipeline_relu];
|
438 |
-
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
|
439 |
-
[encoder setBuffer:id_dst offset:offs_dst atIndex:1];
|
440 |
-
|
441 |
-
const int64_t n = ggml_nelements(dst);
|
442 |
-
|
443 |
-
[encoder dispatchThreadgroups:MTLSizeMake(n, 1, 1) threadsPerThreadgroup:MTLSizeMake(1, 1, 1)];
|
444 |
-
} break;
|
445 |
-
case GGML_OP_GELU:
|
446 |
-
{
|
447 |
-
if (encoder == nil) {
|
448 |
-
encoder = [command_buffer computeCommandEncoder];
|
449 |
-
}
|
450 |
-
|
451 |
-
[encoder setComputePipelineState:ctx->pipeline_gelu];
|
452 |
-
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
|
453 |
-
[encoder setBuffer:id_dst offset:offs_dst atIndex:1];
|
454 |
-
|
455 |
-
const int64_t n = ggml_nelements(dst);
|
456 |
-
|
457 |
-
[encoder dispatchThreadgroups:MTLSizeMake(n, 1, 1) threadsPerThreadgroup:MTLSizeMake(1, 1, 1)];
|
458 |
-
} break;
|
459 |
-
case GGML_OP_SOFT_MAX:
|
460 |
-
{
|
461 |
-
if (encoder == nil) {
|
462 |
-
encoder = [command_buffer computeCommandEncoder];
|
463 |
-
}
|
464 |
-
|
465 |
-
const int nth = 32;
|
466 |
-
|
467 |
-
[encoder setComputePipelineState:ctx->pipeline_soft_max];
|
468 |
-
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
|
469 |
-
[encoder setBuffer:id_dst offset:offs_dst atIndex:1];
|
470 |
-
[encoder setBytes:&ne00 length:sizeof(ne00) atIndex:2];
|
471 |
-
[encoder setBytes:&ne01 length:sizeof(ne01) atIndex:3];
|
472 |
-
[encoder setBytes:&ne02 length:sizeof(ne02) atIndex:4];
|
473 |
-
[encoder setThreadgroupMemoryLength:nth*sizeof(float) atIndex:0];
|
474 |
-
|
475 |
-
[encoder dispatchThreadgroups:MTLSizeMake(ne01, ne02, ne03) threadsPerThreadgroup:MTLSizeMake(nth, 1, 1)];
|
476 |
-
} break;
|
477 |
-
case GGML_OP_DIAG_MASK_INF:
|
478 |
-
{
|
479 |
-
if (encoder == nil) {
|
480 |
-
encoder = [command_buffer computeCommandEncoder];
|
481 |
-
}
|
482 |
-
|
483 |
-
const int n_past = ((int32_t *)(src1->data))[0];
|
484 |
-
|
485 |
-
[encoder setComputePipelineState:ctx->pipeline_diag_mask_inf];
|
486 |
-
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
|
487 |
-
[encoder setBuffer:id_dst offset:offs_dst atIndex:1];
|
488 |
-
[encoder setBytes:&ne00 length:sizeof(ne00) atIndex:2];
|
489 |
-
[encoder setBytes:&ne01 length:sizeof(ne01) atIndex:3];
|
490 |
-
[encoder setBytes:&n_past length:sizeof(int) atIndex:4];
|
491 |
-
|
492 |
-
[encoder dispatchThreadgroups:MTLSizeMake(ne00, ne01, ne02) threadsPerThreadgroup:MTLSizeMake(1, 1, 1)];
|
493 |
-
} break;
|
494 |
-
case GGML_OP_MUL_MAT:
|
495 |
-
{
|
496 |
-
// TODO: needs to be updated after PR: https://github.com/ggerganov/ggml/pull/224
|
497 |
-
|
498 |
-
GGML_ASSERT(ne00 == ne10);
|
499 |
-
GGML_ASSERT(ne02 == ne12);
|
500 |
-
|
501 |
-
if (ggml_is_contiguous(src0) &&
|
502 |
-
ggml_is_contiguous(src1) &&
|
503 |
-
(src0t == GGML_TYPE_F32 || src0t == GGML_TYPE_F16) && ne11 > 1) {
|
504 |
-
|
505 |
-
if (encoder != nil) {
|
506 |
-
[encoder endEncoding];
|
507 |
-
encoder = nil;
|
508 |
-
}
|
509 |
-
|
510 |
-
MPSDataType src0dt = src0t == GGML_TYPE_F32 ? MPSDataTypeFloat32 : MPSDataTypeFloat16;
|
511 |
-
MPSDataType src1dt = src1t == GGML_TYPE_F32 ? MPSDataTypeFloat32 : MPSDataTypeFloat16;
|
512 |
-
|
513 |
-
// for F32 x F32 we use MPS
|
514 |
-
MPSMatrixDescriptor * desc0 = [MPSMatrixDescriptor
|
515 |
-
matrixDescriptorWithRows:ne01 columns:ne00 rowBytes:src0->nb[1] dataType:src0dt];
|
516 |
-
|
517 |
-
MPSMatrixDescriptor * desc1 = [MPSMatrixDescriptor
|
518 |
-
matrixDescriptorWithRows:ne11 columns:ne10 rowBytes:src1->nb[1] dataType:src1dt];
|
519 |
-
|
520 |
-
MPSMatrixDescriptor * desc = [MPSMatrixDescriptor
|
521 |
-
matrixDescriptorWithRows:ne1 columns:ne0 rowBytes:dst->nb[1] dataType:MPSDataTypeFloat32];
|
522 |
-
|
523 |
-
MPSMatrixMultiplication * mul = [[MPSMatrixMultiplication alloc]
|
524 |
-
initWithDevice:ctx->device transposeLeft:false transposeRight:true
|
525 |
-
resultRows:ne11 resultColumns:ne01 interiorColumns:ne00 alpha:1.0 beta:0.0];
|
526 |
-
|
527 |
-
// we need to do ne02 multiplications
|
528 |
-
// TODO: is there a way to do this in parallel - currently very slow ..
|
529 |
-
// TODO: might be possible to offload part of the computation to ANE using Accelerate's CBLAS
|
530 |
-
for (int64_t i02 = 0; i02 < ne02; ++i02) {
|
531 |
-
size_t offs_src0_cur = offs_src0 + i02*nb02;
|
532 |
-
size_t offs_src1_cur = offs_src1 + i02*nb12;
|
533 |
-
size_t offs_dst_cur = offs_dst + i02*nb2;
|
534 |
-
|
535 |
-
MPSMatrix * mat_src0 = [[MPSMatrix alloc] initWithBuffer:id_src0 offset:offs_src0_cur descriptor:desc0];
|
536 |
-
MPSMatrix * mat_src1 = [[MPSMatrix alloc] initWithBuffer:id_src1 offset:offs_src1_cur descriptor:desc1];
|
537 |
-
MPSMatrix * mat_dst = [[MPSMatrix alloc] initWithBuffer:id_dst offset:offs_dst_cur descriptor:desc ];
|
538 |
-
|
539 |
-
[mul encodeToCommandBuffer:command_buffer leftMatrix:mat_src1 rightMatrix:mat_src0 resultMatrix:mat_dst];
|
540 |
-
}
|
541 |
-
} else {
|
542 |
-
if (encoder == nil) {
|
543 |
-
encoder = [command_buffer computeCommandEncoder];
|
544 |
-
}
|
545 |
-
|
546 |
-
int nth0 = 32;
|
547 |
-
int nth1 = 1;
|
548 |
-
|
549 |
-
// use custom matrix x vector kernel
|
550 |
-
switch (src0t) {
|
551 |
-
case GGML_TYPE_F16:
|
552 |
-
{
|
553 |
-
GGML_ASSERT(ne02 == ne12);
|
554 |
-
|
555 |
-
nth0 = 64;
|
556 |
-
nth1 = 1;
|
557 |
-
[encoder setComputePipelineState:ctx->pipeline_mul_mat_f16_f32];
|
558 |
-
} break;
|
559 |
-
case GGML_TYPE_Q4_0:
|
560 |
-
{
|
561 |
-
GGML_ASSERT(ne02 == 1);
|
562 |
-
GGML_ASSERT(ne12 == 1);
|
563 |
-
|
564 |
-
nth0 = 8;
|
565 |
-
nth1 = 8;
|
566 |
-
[encoder setComputePipelineState:ctx->pipeline_mul_mat_q4_0_f32];
|
567 |
-
} break;
|
568 |
-
case GGML_TYPE_Q4_1:
|
569 |
-
{
|
570 |
-
GGML_ASSERT(ne02 == 1);
|
571 |
-
GGML_ASSERT(ne12 == 1);
|
572 |
-
|
573 |
-
nth0 = 8;
|
574 |
-
nth1 = 8;
|
575 |
-
[encoder setComputePipelineState:ctx->pipeline_mul_mat_q4_1_f32];
|
576 |
-
} break;
|
577 |
-
case GGML_TYPE_Q2_K:
|
578 |
-
{
|
579 |
-
GGML_ASSERT(ne02 == 1);
|
580 |
-
GGML_ASSERT(ne12 == 1);
|
581 |
-
|
582 |
-
nth0 = 4;
|
583 |
-
nth1 = 16;
|
584 |
-
[encoder setComputePipelineState:ctx->pipeline_mul_mat_q2_k_f32];
|
585 |
-
} break;
|
586 |
-
case GGML_TYPE_Q3_K:
|
587 |
-
{
|
588 |
-
GGML_ASSERT(ne02 == 1);
|
589 |
-
GGML_ASSERT(ne12 == 1);
|
590 |
-
|
591 |
-
nth0 = 4;
|
592 |
-
nth1 = 16;
|
593 |
-
[encoder setComputePipelineState:ctx->pipeline_mul_mat_q3_k_f32];
|
594 |
-
} break;
|
595 |
-
case GGML_TYPE_Q4_K:
|
596 |
-
{
|
597 |
-
GGML_ASSERT(ne02 == 1);
|
598 |
-
GGML_ASSERT(ne12 == 1);
|
599 |
-
|
600 |
-
nth0 = 4;
|
601 |
-
nth1 = 16;
|
602 |
-
[encoder setComputePipelineState:ctx->pipeline_mul_mat_q4_k_f32];
|
603 |
-
} break;
|
604 |
-
case GGML_TYPE_Q5_K:
|
605 |
-
{
|
606 |
-
GGML_ASSERT(ne02 == 1);
|
607 |
-
GGML_ASSERT(ne12 == 1);
|
608 |
-
|
609 |
-
nth0 = 4;
|
610 |
-
nth1 = 16;
|
611 |
-
[encoder setComputePipelineState:ctx->pipeline_mul_mat_q5_k_f32];
|
612 |
-
} break;
|
613 |
-
case GGML_TYPE_Q6_K:
|
614 |
-
{
|
615 |
-
GGML_ASSERT(ne02 == 1);
|
616 |
-
GGML_ASSERT(ne12 == 1);
|
617 |
-
|
618 |
-
nth0 = 4;
|
619 |
-
nth1 = 16;
|
620 |
-
[encoder setComputePipelineState:ctx->pipeline_mul_mat_q6_k_f32];
|
621 |
-
} break;
|
622 |
-
default:
|
623 |
-
{
|
624 |
-
fprintf(stderr, "Asserting on type %d\n",(int)src0t);
|
625 |
-
GGML_ASSERT(false && "not implemented");
|
626 |
-
}
|
627 |
-
};
|
628 |
-
|
629 |
-
|
630 |
-
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
|
631 |
-
[encoder setBuffer:id_src1 offset:offs_src1 atIndex:1];
|
632 |
-
[encoder setBuffer:id_dst offset:offs_dst atIndex:2];
|
633 |
-
[encoder setBytes:&ne00 length:sizeof(ne00) atIndex:3];
|
634 |
-
[encoder setBytes:&ne01 length:sizeof(ne01) atIndex:4];
|
635 |
-
[encoder setBytes:&nb00 length:sizeof(nb00) atIndex:5];
|
636 |
-
[encoder setBytes:&nb01 length:sizeof(nb01) atIndex:6];
|
637 |
-
[encoder setBytes:&nb02 length:sizeof(nb02) atIndex:7];
|
638 |
-
[encoder setBytes:&ne10 length:sizeof(ne10) atIndex:8];
|
639 |
-
[encoder setBytes:&ne11 length:sizeof(ne11) atIndex:9];
|
640 |
-
[encoder setBytes:&nb10 length:sizeof(nb10) atIndex:10];
|
641 |
-
[encoder setBytes:&nb11 length:sizeof(nb11) atIndex:11];
|
642 |
-
[encoder setBytes:&nb12 length:sizeof(nb12) atIndex:12];
|
643 |
-
[encoder setBytes:&ne0 length:sizeof(ne0) atIndex:13];
|
644 |
-
[encoder setBytes:&ne1 length:sizeof(ne1) atIndex:14];
|
645 |
-
|
646 |
-
if (src0t == GGML_TYPE_Q4_0 || src0t == GGML_TYPE_Q4_1) {
|
647 |
-
[encoder setThreadgroupMemoryLength:nth0*nth1*sizeof(float) atIndex:0];
|
648 |
-
[encoder dispatchThreadgroups:MTLSizeMake(ne01, ne11, 1) threadsPerThreadgroup:MTLSizeMake(nth0, nth1, 1)];
|
649 |
-
}
|
650 |
-
else if (src0t == GGML_TYPE_Q2_K ||
|
651 |
-
src0t == GGML_TYPE_Q3_K ||
|
652 |
-
src0t == GGML_TYPE_Q4_K ||
|
653 |
-
src0t == GGML_TYPE_Q5_K ||
|
654 |
-
src0t == GGML_TYPE_Q6_K) {
|
655 |
-
[encoder setThreadgroupMemoryLength:nth0*nth1*sizeof(float) atIndex:0];
|
656 |
-
[encoder dispatchThreadgroups:MTLSizeMake(ne01, 1, 1) threadsPerThreadgroup:MTLSizeMake(nth0, nth1, 1)];
|
657 |
-
} else {
|
658 |
-
[encoder setThreadgroupMemoryLength:nth0*sizeof(float) atIndex:0];
|
659 |
-
[encoder dispatchThreadgroups:MTLSizeMake(ne01, ne11, ne12) threadsPerThreadgroup:MTLSizeMake(nth0, nth1, 1)];
|
660 |
-
}
|
661 |
-
}
|
662 |
-
} break;
|
663 |
-
case GGML_OP_GET_ROWS:
|
664 |
-
{
|
665 |
-
if (encoder == nil) {
|
666 |
-
encoder = [command_buffer computeCommandEncoder];
|
667 |
-
}
|
668 |
-
|
669 |
-
switch (src0->type) {
|
670 |
-
case GGML_TYPE_F16: [encoder setComputePipelineState:ctx->pipeline_get_rows_f16]; break;
|
671 |
-
case GGML_TYPE_Q4_0: [encoder setComputePipelineState:ctx->pipeline_get_rows_q4_0]; break;
|
672 |
-
case GGML_TYPE_Q4_1: [encoder setComputePipelineState:ctx->pipeline_get_rows_q4_1]; break;
|
673 |
-
case GGML_TYPE_Q2_K: [encoder setComputePipelineState:ctx->pipeline_get_rows_q2_k]; break;
|
674 |
-
case GGML_TYPE_Q3_K: [encoder setComputePipelineState:ctx->pipeline_get_rows_q3_k]; break;
|
675 |
-
case GGML_TYPE_Q4_K: [encoder setComputePipelineState:ctx->pipeline_get_rows_q4_k]; break;
|
676 |
-
case GGML_TYPE_Q5_K: [encoder setComputePipelineState:ctx->pipeline_get_rows_q5_k]; break;
|
677 |
-
case GGML_TYPE_Q6_K: [encoder setComputePipelineState:ctx->pipeline_get_rows_q6_k]; break;
|
678 |
-
default: GGML_ASSERT(false && "not implemented");
|
679 |
-
}
|
680 |
-
|
681 |
-
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
|
682 |
-
[encoder setBuffer:id_src1 offset:offs_src1 atIndex:1];
|
683 |
-
[encoder setBuffer:id_dst offset:offs_dst atIndex:2];
|
684 |
-
[encoder setBytes:&(src0->ne[0]) length:sizeof( int64_t) atIndex:3];
|
685 |
-
[encoder setBytes:&(src0->nb[1]) length:sizeof(uint64_t) atIndex:4];
|
686 |
-
[encoder setBytes:&(dst->nb[1]) length:sizeof(uint64_t) atIndex:5];
|
687 |
-
|
688 |
-
const int64_t n = ggml_nelements(src1);
|
689 |
-
|
690 |
-
[encoder dispatchThreadgroups:MTLSizeMake(n, 1, 1) threadsPerThreadgroup:MTLSizeMake(1, 1, 1)];
|
691 |
-
} break;
|
692 |
-
case GGML_OP_RMS_NORM:
|
693 |
-
{
|
694 |
-
if (encoder == nil) {
|
695 |
-
encoder = [command_buffer computeCommandEncoder];
|
696 |
-
}
|
697 |
-
|
698 |
-
const float eps = 1e-6f;
|
699 |
-
|
700 |
-
const int nth = 256;
|
701 |
-
|
702 |
-
[encoder setComputePipelineState:ctx->pipeline_rms_norm];
|
703 |
-
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
|
704 |
-
[encoder setBuffer:id_dst offset:offs_dst atIndex:1];
|
705 |
-
[encoder setBytes:&ne00 length:sizeof( int64_t) atIndex:2];
|
706 |
-
[encoder setBytes:&nb01 length:sizeof(uint64_t) atIndex:3];
|
707 |
-
[encoder setBytes:&eps length:sizeof( float) atIndex:4];
|
708 |
-
[encoder setThreadgroupMemoryLength:nth*sizeof(float) atIndex:0];
|
709 |
-
|
710 |
-
const int64_t nrows = ggml_nrows(src0);
|
711 |
-
|
712 |
-
[encoder dispatchThreadgroups:MTLSizeMake(nrows, 1, 1) threadsPerThreadgroup:MTLSizeMake(nth, 1, 1)];
|
713 |
-
} break;
|
714 |
-
case GGML_OP_ROPE:
|
715 |
-
{
|
716 |
-
if (encoder == nil) {
|
717 |
-
encoder = [command_buffer computeCommandEncoder];
|
718 |
-
}
|
719 |
-
|
720 |
-
const int n_dims = ((int32_t *) src1->data)[1];
|
721 |
-
const int mode = ((int32_t *) src1->data)[2];
|
722 |
-
|
723 |
-
const int n_past = ((int32_t *)(src1->data))[0];
|
724 |
-
|
725 |
-
[encoder setComputePipelineState:ctx->pipeline_rope];
|
726 |
-
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
|
727 |
-
[encoder setBuffer:id_dst offset:offs_dst atIndex:1];
|
728 |
-
[encoder setBytes:&ne00 length:sizeof( int64_t) atIndex:2];
|
729 |
-
[encoder setBytes:&ne01 length:sizeof( int64_t) atIndex:3];
|
730 |
-
[encoder setBytes:&ne02 length:sizeof( int64_t) atIndex:4];
|
731 |
-
[encoder setBytes:&ne03 length:sizeof( int64_t) atIndex:5];
|
732 |
-
[encoder setBytes:&nb00 length:sizeof(uint64_t) atIndex:6];
|
733 |
-
[encoder setBytes:&nb01 length:sizeof(uint64_t) atIndex:7];
|
734 |
-
[encoder setBytes:&nb02 length:sizeof(uint64_t) atIndex:8];
|
735 |
-
[encoder setBytes:&nb03 length:sizeof(uint64_t) atIndex:9];
|
736 |
-
[encoder setBytes:&ne0 length:sizeof( int64_t) atIndex:10];
|
737 |
-
[encoder setBytes:&ne1 length:sizeof( int64_t) atIndex:11];
|
738 |
-
[encoder setBytes:&ne2 length:sizeof( int64_t) atIndex:12];
|
739 |
-
[encoder setBytes:&ne3 length:sizeof( int64_t) atIndex:13];
|
740 |
-
[encoder setBytes:&nb0 length:sizeof(uint64_t) atIndex:14];
|
741 |
-
[encoder setBytes:&nb1 length:sizeof(uint64_t) atIndex:15];
|
742 |
-
[encoder setBytes:&nb2 length:sizeof(uint64_t) atIndex:16];
|
743 |
-
[encoder setBytes:&nb3 length:sizeof(uint64_t) atIndex:17];
|
744 |
-
[encoder setBytes:&n_past length:sizeof( int) atIndex:18];
|
745 |
-
[encoder setBytes:&n_dims length:sizeof( int) atIndex:19];
|
746 |
-
[encoder setBytes:&mode length:sizeof( int) atIndex:20];
|
747 |
-
|
748 |
-
[encoder dispatchThreadgroups:MTLSizeMake(ne01, ne02, ne03) threadsPerThreadgroup:MTLSizeMake(1, 1, 1)];
|
749 |
-
} break;
|
750 |
-
case GGML_OP_CPY:
|
751 |
-
{
|
752 |
-
if (encoder == nil) {
|
753 |
-
encoder = [command_buffer computeCommandEncoder];
|
754 |
-
}
|
755 |
-
|
756 |
-
const int nth = 32;
|
757 |
-
|
758 |
-
switch (src0t) {
|
759 |
-
case GGML_TYPE_F32:
|
760 |
-
{
|
761 |
-
switch (dstt) {
|
762 |
-
case GGML_TYPE_F16: [encoder setComputePipelineState:ctx->pipeline_cpy_f32_f16]; break;
|
763 |
-
case GGML_TYPE_F32: [encoder setComputePipelineState:ctx->pipeline_cpy_f32_f32]; break;
|
764 |
-
default: GGML_ASSERT(false && "not implemented");
|
765 |
-
};
|
766 |
-
} break;
|
767 |
-
default: GGML_ASSERT(false && "not implemented");
|
768 |
-
}
|
769 |
-
|
770 |
-
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
|
771 |
-
[encoder setBuffer:id_dst offset:offs_dst atIndex:1];
|
772 |
-
[encoder setBytes:&ne00 length:sizeof( int64_t) atIndex:2];
|
773 |
-
[encoder setBytes:&ne01 length:sizeof( int64_t) atIndex:3];
|
774 |
-
[encoder setBytes:&ne02 length:sizeof( int64_t) atIndex:4];
|
775 |
-
[encoder setBytes:&ne03 length:sizeof( int64_t) atIndex:5];
|
776 |
-
[encoder setBytes:&nb00 length:sizeof(uint64_t) atIndex:6];
|
777 |
-
[encoder setBytes:&nb01 length:sizeof(uint64_t) atIndex:7];
|
778 |
-
[encoder setBytes:&nb02 length:sizeof(uint64_t) atIndex:8];
|
779 |
-
[encoder setBytes:&nb03 length:sizeof(uint64_t) atIndex:9];
|
780 |
-
[encoder setBytes:&ne0 length:sizeof( int64_t) atIndex:10];
|
781 |
-
[encoder setBytes:&ne1 length:sizeof( int64_t) atIndex:11];
|
782 |
-
[encoder setBytes:&ne2 length:sizeof( int64_t) atIndex:12];
|
783 |
-
[encoder setBytes:&ne3 length:sizeof( int64_t) atIndex:13];
|
784 |
-
[encoder setBytes:&nb0 length:sizeof(uint64_t) atIndex:14];
|
785 |
-
[encoder setBytes:&nb1 length:sizeof(uint64_t) atIndex:15];
|
786 |
-
[encoder setBytes:&nb2 length:sizeof(uint64_t) atIndex:16];
|
787 |
-
[encoder setBytes:&nb3 length:sizeof(uint64_t) atIndex:17];
|
788 |
-
|
789 |
-
[encoder dispatchThreadgroups:MTLSizeMake(ne01, ne02, ne03) threadsPerThreadgroup:MTLSizeMake(nth, 1, 1)];
|
790 |
-
} break;
|
791 |
-
default:
|
792 |
-
fprintf(stderr, "%s: node %3d, op = %8s not implemented\n", __func__, i, ggml_op_name(dst->op));
|
793 |
-
GGML_ASSERT(false);
|
794 |
-
}
|
795 |
-
}
|
796 |
|
797 |
-
|
798 |
-
[
|
799 |
-
encoder = nil;
|
800 |
}
|
801 |
|
802 |
-
|
803 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
804 |
|
805 |
-
|
806 |
-
|
807 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
808 |
|
809 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
810 |
}
|
|
|
|
|
|
|
|
|
|
|
811 |
}
|
|
|
57 |
GGML_METAL_DECL_KERNEL(get_rows_q5_k);
|
58 |
GGML_METAL_DECL_KERNEL(get_rows_q6_k);
|
59 |
GGML_METAL_DECL_KERNEL(rms_norm);
|
60 |
+
GGML_METAL_DECL_KERNEL(norm);
|
61 |
GGML_METAL_DECL_KERNEL(mul_mat_f16_f32);
|
62 |
GGML_METAL_DECL_KERNEL(mul_mat_q4_0_f32);
|
63 |
GGML_METAL_DECL_KERNEL(mul_mat_q4_1_f32);
|
|
|
67 |
GGML_METAL_DECL_KERNEL(mul_mat_q5_k_f32);
|
68 |
GGML_METAL_DECL_KERNEL(mul_mat_q6_k_f32);
|
69 |
GGML_METAL_DECL_KERNEL(rope);
|
70 |
+
GGML_METAL_DECL_KERNEL(alibi_f32);
|
71 |
GGML_METAL_DECL_KERNEL(cpy_f32_f16);
|
72 |
GGML_METAL_DECL_KERNEL(cpy_f32_f32);
|
73 |
+
GGML_METAL_DECL_KERNEL(cpy_f16_f16);
|
74 |
|
75 |
#undef GGML_METAL_DECL_KERNEL
|
76 |
};
|
|
|
165 |
GGML_METAL_ADD_KERNEL(get_rows_q5_k);
|
166 |
GGML_METAL_ADD_KERNEL(get_rows_q6_k);
|
167 |
GGML_METAL_ADD_KERNEL(rms_norm);
|
168 |
+
GGML_METAL_ADD_KERNEL(norm);
|
169 |
GGML_METAL_ADD_KERNEL(mul_mat_f16_f32);
|
170 |
GGML_METAL_ADD_KERNEL(mul_mat_q4_0_f32);
|
171 |
GGML_METAL_ADD_KERNEL(mul_mat_q4_1_f32);
|
|
|
175 |
GGML_METAL_ADD_KERNEL(mul_mat_q5_k_f32);
|
176 |
GGML_METAL_ADD_KERNEL(mul_mat_q6_k_f32);
|
177 |
GGML_METAL_ADD_KERNEL(rope);
|
178 |
+
GGML_METAL_ADD_KERNEL(alibi_f32);
|
179 |
GGML_METAL_ADD_KERNEL(cpy_f32_f16);
|
180 |
GGML_METAL_ADD_KERNEL(cpy_f32_f32);
|
181 |
+
GGML_METAL_ADD_KERNEL(cpy_f16_f16);
|
182 |
|
183 |
#undef GGML_METAL_ADD_KERNEL
|
184 |
}
|
|
|
290 |
|
291 |
void ggml_metal_graph_compute(
|
292 |
struct ggml_metal_context * ctx,
|
293 |
+
struct ggml_cgraph * gf) {
|
294 |
metal_printf("%s: evaluating graph\n", __func__);
|
295 |
|
296 |
+
// create multiple command buffers and enqueue them
|
297 |
+
// then, we encode the graph into the command buffers in parallel
|
298 |
+
|
299 |
+
const int n_cb = gf->n_threads;
|
300 |
+
|
301 |
+
NSMutableArray * command_buffers = [NSMutableArray arrayWithCapacity:n_cb];
|
302 |
+
|
303 |
+
for (int i = 0; i < n_cb; ++i) {
|
304 |
+
command_buffers[i] = [ctx->queue commandBuffer];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
305 |
|
306 |
+
// enqueue the command buffers in order to specify their execution order
|
307 |
+
[command_buffers[i] enqueue];
|
|
|
308 |
}
|
309 |
|
310 |
+
// TODO: is this the best way to start threads?
|
311 |
+
dispatch_queue_t queue = dispatch_queue_create("llama.cpp", DISPATCH_QUEUE_CONCURRENT);
|
312 |
+
|
313 |
+
for (int cb_idx = 0; cb_idx < n_cb; ++cb_idx) {
|
314 |
+
const int n_nodes_per_cb = (gf->n_nodes + n_cb - 1) / n_cb;
|
315 |
+
|
316 |
+
dispatch_async(queue, ^{
|
317 |
+
size_t offs_src0 = 0;
|
318 |
+
size_t offs_src1 = 0;
|
319 |
+
size_t offs_dst = 0;
|
320 |
+
|
321 |
+
id<MTLCommandBuffer> command_buffer = command_buffers[cb_idx];
|
322 |
+
|
323 |
+
id<MTLComputeCommandEncoder> encoder = nil;
|
324 |
+
|
325 |
+
const int node_start = (cb_idx + 0) * n_nodes_per_cb;
|
326 |
+
const int node_end = (cb_idx == n_cb - 1) ? gf->n_nodes : (cb_idx + 1) * n_nodes_per_cb;
|
327 |
+
|
328 |
+
for (int i = node_start; i < node_end; ++i) {
|
329 |
+
metal_printf("%s: encoding node %3d, op = %8s\n", __func__, i, ggml_op_name(gf->nodes[i]->op));
|
330 |
+
|
331 |
+
struct ggml_tensor * src0 = gf->nodes[i]->src0;
|
332 |
+
struct ggml_tensor * src1 = gf->nodes[i]->src1;
|
333 |
+
struct ggml_tensor * dst = gf->nodes[i];
|
334 |
+
|
335 |
+
const int64_t ne00 = src0 ? src0->ne[0] : 0;
|
336 |
+
const int64_t ne01 = src0 ? src0->ne[1] : 0;
|
337 |
+
const int64_t ne02 = src0 ? src0->ne[2] : 0;
|
338 |
+
const int64_t ne03 = src0 ? src0->ne[3] : 0;
|
339 |
+
|
340 |
+
const uint64_t nb00 = src0 ? src0->nb[0] : 0;
|
341 |
+
const uint64_t nb01 = src0 ? src0->nb[1] : 0;
|
342 |
+
const uint64_t nb02 = src0 ? src0->nb[2] : 0;
|
343 |
+
const uint64_t nb03 = src0 ? src0->nb[3] : 0;
|
344 |
+
|
345 |
+
const int64_t ne10 = src1 ? src1->ne[0] : 0;
|
346 |
+
const int64_t ne11 = src1 ? src1->ne[1] : 0;
|
347 |
+
const int64_t ne12 = src1 ? src1->ne[2] : 0;
|
348 |
+
const int64_t ne13 = src1 ? src1->ne[3] : 0; UNUSED(ne13);
|
349 |
+
|
350 |
+
const uint64_t nb10 = src1 ? src1->nb[0] : 0;
|
351 |
+
const uint64_t nb11 = src1 ? src1->nb[1] : 0;
|
352 |
+
const uint64_t nb12 = src1 ? src1->nb[2] : 0;
|
353 |
+
const uint64_t nb13 = src1 ? src1->nb[3] : 0; UNUSED(nb13);
|
354 |
+
|
355 |
+
const int64_t ne0 = dst ? dst->ne[0] : 0;
|
356 |
+
const int64_t ne1 = dst ? dst->ne[1] : 0;
|
357 |
+
const int64_t ne2 = dst ? dst->ne[2] : 0;
|
358 |
+
const int64_t ne3 = dst ? dst->ne[3] : 0;
|
359 |
+
|
360 |
+
const uint64_t nb0 = dst ? dst->nb[0] : 0;
|
361 |
+
const uint64_t nb1 = dst ? dst->nb[1] : 0;
|
362 |
+
const uint64_t nb2 = dst ? dst->nb[2] : 0;
|
363 |
+
const uint64_t nb3 = dst ? dst->nb[3] : 0;
|
364 |
+
|
365 |
+
const enum ggml_type src0t = src0 ? src0->type : GGML_TYPE_COUNT;
|
366 |
+
const enum ggml_type src1t = src1 ? src1->type : GGML_TYPE_COUNT;
|
367 |
+
const enum ggml_type dstt = dst ? dst->type : GGML_TYPE_COUNT;
|
368 |
+
|
369 |
+
id<MTLBuffer> id_src0 = src0 ? ggml_metal_get_buffer(ctx, src0, &offs_src0) : nil;
|
370 |
+
id<MTLBuffer> id_src1 = src1 ? ggml_metal_get_buffer(ctx, src1, &offs_src1) : nil;
|
371 |
+
id<MTLBuffer> id_dst = dst ? ggml_metal_get_buffer(ctx, dst, &offs_dst) : nil;
|
372 |
+
|
373 |
+
//metal_printf("%s: op - %s\n", __func__, ggml_op_name(dst->op));
|
374 |
+
//if (src0) {
|
375 |
+
// metal_printf("%s: src0 - %4s [%5lld, %5lld, %5lld], %d, %s\n", __func__, ggml_type_name(src0t), ne00, ne01, ne02,
|
376 |
+
// ggml_is_contiguous(src0), src0->name);
|
377 |
+
//}
|
378 |
+
//if (src1) {
|
379 |
+
// metal_printf("%s: src1 - %4s [%5lld, %5lld, %5lld], %d, %s\n", __func__, ggml_type_name(src1t), ne10, ne11, ne12,
|
380 |
+
// ggml_is_contiguous(src1), src1->name);
|
381 |
+
//}
|
382 |
+
//if (dst) {
|
383 |
+
// metal_printf("%s: dst - %4s [%5lld, %5lld, %5lld], 1, %s\n", __func__, ggml_type_name(dstt), ne0, ne1, ne2,
|
384 |
+
// dst->name);
|
385 |
+
//}
|
386 |
+
|
387 |
+
switch (dst->op) {
|
388 |
+
case GGML_OP_RESHAPE:
|
389 |
+
case GGML_OP_VIEW:
|
390 |
+
case GGML_OP_TRANSPOSE:
|
391 |
+
case GGML_OP_PERMUTE:
|
392 |
+
{
|
393 |
+
// noop
|
394 |
+
} break;
|
395 |
+
case GGML_OP_ADD:
|
396 |
+
{
|
397 |
+
if (encoder == nil) {
|
398 |
+
encoder = [command_buffer computeCommandEncoder];
|
399 |
+
}
|
400 |
+
|
401 |
+
[encoder setComputePipelineState:ctx->pipeline_add];
|
402 |
+
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
|
403 |
+
[encoder setBuffer:id_src1 offset:offs_src1 atIndex:1];
|
404 |
+
[encoder setBuffer:id_dst offset:offs_dst atIndex:2];
|
405 |
+
|
406 |
+
const int64_t n = ggml_nelements(dst);
|
407 |
+
|
408 |
+
[encoder dispatchThreadgroups:MTLSizeMake(n, 1, 1) threadsPerThreadgroup:MTLSizeMake(1, 1, 1)];
|
409 |
+
} break;
|
410 |
+
case GGML_OP_MUL:
|
411 |
+
{
|
412 |
+
if (encoder == nil) {
|
413 |
+
encoder = [command_buffer computeCommandEncoder];
|
414 |
+
}
|
415 |
+
|
416 |
+
if (ggml_nelements(src1) == ne10) {
|
417 |
+
// src1 is a row
|
418 |
+
[encoder setComputePipelineState:ctx->pipeline_mul_row];
|
419 |
+
} else {
|
420 |
+
[encoder setComputePipelineState:ctx->pipeline_mul];
|
421 |
+
}
|
422 |
+
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
|
423 |
+
[encoder setBuffer:id_src1 offset:offs_src1 atIndex:1];
|
424 |
+
[encoder setBuffer:id_dst offset:offs_dst atIndex:2];
|
425 |
+
[encoder setBytes:&ne00 length:sizeof(ne00) atIndex:3];
|
426 |
+
|
427 |
+
const int64_t n = ggml_nelements(dst);
|
428 |
+
|
429 |
+
[encoder dispatchThreadgroups:MTLSizeMake(n, 1, 1) threadsPerThreadgroup:MTLSizeMake(1, 1, 1)];
|
430 |
+
} break;
|
431 |
+
case GGML_OP_SCALE:
|
432 |
+
{
|
433 |
+
if (encoder == nil) {
|
434 |
+
encoder = [command_buffer computeCommandEncoder];
|
435 |
+
}
|
436 |
+
|
437 |
+
const float scale = *(const float *) src1->data;
|
438 |
+
|
439 |
+
[encoder setComputePipelineState:ctx->pipeline_scale];
|
440 |
+
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
|
441 |
+
[encoder setBuffer:id_dst offset:offs_dst atIndex:1];
|
442 |
+
[encoder setBytes:&scale length:sizeof(scale) atIndex:2];
|
443 |
+
|
444 |
+
const int64_t n = ggml_nelements(dst);
|
445 |
+
|
446 |
+
[encoder dispatchThreadgroups:MTLSizeMake(n, 1, 1) threadsPerThreadgroup:MTLSizeMake(1, 1, 1)];
|
447 |
+
} break;
|
448 |
+
case GGML_OP_SILU:
|
449 |
+
{
|
450 |
+
if (encoder == nil) {
|
451 |
+
encoder = [command_buffer computeCommandEncoder];
|
452 |
+
}
|
453 |
+
|
454 |
+
[encoder setComputePipelineState:ctx->pipeline_silu];
|
455 |
+
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
|
456 |
+
[encoder setBuffer:id_dst offset:offs_dst atIndex:1];
|
457 |
+
|
458 |
+
const int64_t n = ggml_nelements(dst);
|
459 |
+
|
460 |
+
[encoder dispatchThreadgroups:MTLSizeMake(n, 1, 1) threadsPerThreadgroup:MTLSizeMake(1, 1, 1)];
|
461 |
+
} break;
|
462 |
+
case GGML_OP_RELU:
|
463 |
+
{
|
464 |
+
if (encoder == nil) {
|
465 |
+
encoder = [command_buffer computeCommandEncoder];
|
466 |
+
}
|
467 |
+
|
468 |
+
[encoder setComputePipelineState:ctx->pipeline_relu];
|
469 |
+
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
|
470 |
+
[encoder setBuffer:id_dst offset:offs_dst atIndex:1];
|
471 |
+
|
472 |
+
const int64_t n = ggml_nelements(dst);
|
473 |
+
|
474 |
+
[encoder dispatchThreadgroups:MTLSizeMake(n, 1, 1) threadsPerThreadgroup:MTLSizeMake(1, 1, 1)];
|
475 |
+
} break;
|
476 |
+
case GGML_OP_GELU:
|
477 |
+
{
|
478 |
+
if (encoder == nil) {
|
479 |
+
encoder = [command_buffer computeCommandEncoder];
|
480 |
+
}
|
481 |
+
|
482 |
+
[encoder setComputePipelineState:ctx->pipeline_gelu];
|
483 |
+
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
|
484 |
+
[encoder setBuffer:id_dst offset:offs_dst atIndex:1];
|
485 |
+
|
486 |
+
const int64_t n = ggml_nelements(dst);
|
487 |
+
|
488 |
+
[encoder dispatchThreadgroups:MTLSizeMake(n, 1, 1) threadsPerThreadgroup:MTLSizeMake(1, 1, 1)];
|
489 |
+
} break;
|
490 |
+
case GGML_OP_SOFT_MAX:
|
491 |
+
{
|
492 |
+
if (encoder == nil) {
|
493 |
+
encoder = [command_buffer computeCommandEncoder];
|
494 |
+
}
|
495 |
+
|
496 |
+
const int nth = 32;
|
497 |
+
|
498 |
+
[encoder setComputePipelineState:ctx->pipeline_soft_max];
|
499 |
+
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
|
500 |
+
[encoder setBuffer:id_dst offset:offs_dst atIndex:1];
|
501 |
+
[encoder setBytes:&ne00 length:sizeof(ne00) atIndex:2];
|
502 |
+
[encoder setBytes:&ne01 length:sizeof(ne01) atIndex:3];
|
503 |
+
[encoder setBytes:&ne02 length:sizeof(ne02) atIndex:4];
|
504 |
+
[encoder setThreadgroupMemoryLength:nth*sizeof(float) atIndex:0];
|
505 |
+
|
506 |
+
[encoder dispatchThreadgroups:MTLSizeMake(ne01, ne02, ne03) threadsPerThreadgroup:MTLSizeMake(nth, 1, 1)];
|
507 |
+
} break;
|
508 |
+
case GGML_OP_DIAG_MASK_INF:
|
509 |
+
{
|
510 |
+
if (encoder == nil) {
|
511 |
+
encoder = [command_buffer computeCommandEncoder];
|
512 |
+
}
|
513 |
+
|
514 |
+
const int n_past = ((int32_t *)(src1->data))[0];
|
515 |
+
|
516 |
+
[encoder setComputePipelineState:ctx->pipeline_diag_mask_inf];
|
517 |
+
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
|
518 |
+
[encoder setBuffer:id_dst offset:offs_dst atIndex:1];
|
519 |
+
[encoder setBytes:&ne00 length:sizeof(ne00) atIndex:2];
|
520 |
+
[encoder setBytes:&ne01 length:sizeof(ne01) atIndex:3];
|
521 |
+
[encoder setBytes:&n_past length:sizeof(int) atIndex:4];
|
522 |
+
|
523 |
+
[encoder dispatchThreadgroups:MTLSizeMake(ne00, ne01, ne02) threadsPerThreadgroup:MTLSizeMake(1, 1, 1)];
|
524 |
+
} break;
|
525 |
+
case GGML_OP_MUL_MAT:
|
526 |
+
{
|
527 |
+
// TODO: needs to be updated after PR: https://github.com/ggerganov/ggml/pull/224
|
528 |
+
|
529 |
+
GGML_ASSERT(ne00 == ne10);
|
530 |
+
GGML_ASSERT(ne02 == ne12);
|
531 |
+
|
532 |
+
if (ggml_is_contiguous(src0) &&
|
533 |
+
ggml_is_contiguous(src1) &&
|
534 |
+
(src0t == GGML_TYPE_F32 || src0t == GGML_TYPE_F16) && ne11 > 1) {
|
535 |
+
|
536 |
+
if (encoder != nil) {
|
537 |
+
[encoder endEncoding];
|
538 |
+
encoder = nil;
|
539 |
+
}
|
540 |
|
541 |
+
MPSDataType src0dt = src0t == GGML_TYPE_F32 ? MPSDataTypeFloat32 : MPSDataTypeFloat16;
|
542 |
+
MPSDataType src1dt = src1t == GGML_TYPE_F32 ? MPSDataTypeFloat32 : MPSDataTypeFloat16;
|
543 |
+
|
544 |
+
// for F32 x F32 we use MPS
|
545 |
+
MPSMatrixDescriptor * desc0 = [MPSMatrixDescriptor
|
546 |
+
matrixDescriptorWithRows:ne01 columns:ne00 rowBytes:src0->nb[1] dataType:src0dt];
|
547 |
+
|
548 |
+
MPSMatrixDescriptor * desc1 = [MPSMatrixDescriptor
|
549 |
+
matrixDescriptorWithRows:ne11 columns:ne10 rowBytes:src1->nb[1] dataType:src1dt];
|
550 |
+
|
551 |
+
MPSMatrixDescriptor * desc = [MPSMatrixDescriptor
|
552 |
+
matrixDescriptorWithRows:ne1 columns:ne0 rowBytes:dst->nb[1] dataType:MPSDataTypeFloat32];
|
553 |
+
|
554 |
+
MPSMatrixMultiplication * mul = [[MPSMatrixMultiplication alloc]
|
555 |
+
initWithDevice:ctx->device transposeLeft:false transposeRight:true
|
556 |
+
resultRows:ne11 resultColumns:ne01 interiorColumns:ne00 alpha:1.0 beta:0.0];
|
557 |
+
|
558 |
+
// we need to do ne02 multiplications
|
559 |
+
// TODO: is there a way to do this in parallel - currently very slow ..
|
560 |
+
// TODO: might be possible to offload part of the computation to ANE using Accelerate's CBLAS
|
561 |
+
for (int64_t i02 = 0; i02 < ne02; ++i02) {
|
562 |
+
size_t offs_src0_cur = offs_src0 + i02*nb02;
|
563 |
+
size_t offs_src1_cur = offs_src1 + i02*nb12;
|
564 |
+
size_t offs_dst_cur = offs_dst + i02*nb2;
|
565 |
|
566 |
+
MPSMatrix * mat_src0 = [[MPSMatrix alloc] initWithBuffer:id_src0 offset:offs_src0_cur descriptor:desc0];
|
567 |
+
MPSMatrix * mat_src1 = [[MPSMatrix alloc] initWithBuffer:id_src1 offset:offs_src1_cur descriptor:desc1];
|
568 |
+
MPSMatrix * mat_dst = [[MPSMatrix alloc] initWithBuffer:id_dst offset:offs_dst_cur descriptor:desc ];
|
569 |
+
|
570 |
+
[mul encodeToCommandBuffer:command_buffer leftMatrix:mat_src1 rightMatrix:mat_src0 resultMatrix:mat_dst];
|
571 |
+
}
|
572 |
+
} else {
|
573 |
+
if (encoder == nil) {
|
574 |
+
encoder = [command_buffer computeCommandEncoder];
|
575 |
+
}
|
576 |
+
|
577 |
+
int nth0 = 32;
|
578 |
+
int nth1 = 1;
|
579 |
+
|
580 |
+
// use custom matrix x vector kernel
|
581 |
+
switch (src0t) {
|
582 |
+
case GGML_TYPE_F16:
|
583 |
+
{
|
584 |
+
GGML_ASSERT(ne02 == ne12);
|
585 |
+
|
586 |
+
nth0 = 64;
|
587 |
+
nth1 = 1;
|
588 |
+
[encoder setComputePipelineState:ctx->pipeline_mul_mat_f16_f32];
|
589 |
+
} break;
|
590 |
+
case GGML_TYPE_Q4_0:
|
591 |
+
{
|
592 |
+
GGML_ASSERT(ne02 == 1);
|
593 |
+
GGML_ASSERT(ne12 == 1);
|
594 |
+
|
595 |
+
nth0 = 8;
|
596 |
+
nth1 = 8;
|
597 |
+
[encoder setComputePipelineState:ctx->pipeline_mul_mat_q4_0_f32];
|
598 |
+
} break;
|
599 |
+
case GGML_TYPE_Q4_1:
|
600 |
+
{
|
601 |
+
GGML_ASSERT(ne02 == 1);
|
602 |
+
GGML_ASSERT(ne12 == 1);
|
603 |
+
|
604 |
+
nth0 = 8;
|
605 |
+
nth1 = 8;
|
606 |
+
[encoder setComputePipelineState:ctx->pipeline_mul_mat_q4_1_f32];
|
607 |
+
} break;
|
608 |
+
case GGML_TYPE_Q2_K:
|
609 |
+
{
|
610 |
+
GGML_ASSERT(ne02 == 1);
|
611 |
+
GGML_ASSERT(ne12 == 1);
|
612 |
+
|
613 |
+
nth0 = 4;
|
614 |
+
nth1 = 16;
|
615 |
+
[encoder setComputePipelineState:ctx->pipeline_mul_mat_q2_k_f32];
|
616 |
+
} break;
|
617 |
+
case GGML_TYPE_Q3_K:
|
618 |
+
{
|
619 |
+
GGML_ASSERT(ne02 == 1);
|
620 |
+
GGML_ASSERT(ne12 == 1);
|
621 |
+
|
622 |
+
nth0 = 4;
|
623 |
+
nth1 = 16;
|
624 |
+
[encoder setComputePipelineState:ctx->pipeline_mul_mat_q3_k_f32];
|
625 |
+
} break;
|
626 |
+
case GGML_TYPE_Q4_K:
|
627 |
+
{
|
628 |
+
GGML_ASSERT(ne02 == 1);
|
629 |
+
GGML_ASSERT(ne12 == 1);
|
630 |
+
|
631 |
+
nth0 = 4;
|
632 |
+
nth1 = 16;
|
633 |
+
[encoder setComputePipelineState:ctx->pipeline_mul_mat_q4_k_f32];
|
634 |
+
} break;
|
635 |
+
case GGML_TYPE_Q5_K:
|
636 |
+
{
|
637 |
+
GGML_ASSERT(ne02 == 1);
|
638 |
+
GGML_ASSERT(ne12 == 1);
|
639 |
+
|
640 |
+
nth0 = 4;
|
641 |
+
nth1 = 16;
|
642 |
+
[encoder setComputePipelineState:ctx->pipeline_mul_mat_q5_k_f32];
|
643 |
+
} break;
|
644 |
+
case GGML_TYPE_Q6_K:
|
645 |
+
{
|
646 |
+
GGML_ASSERT(ne02 == 1);
|
647 |
+
GGML_ASSERT(ne12 == 1);
|
648 |
+
|
649 |
+
nth0 = 4;
|
650 |
+
nth1 = 16;
|
651 |
+
[encoder setComputePipelineState:ctx->pipeline_mul_mat_q6_k_f32];
|
652 |
+
} break;
|
653 |
+
default:
|
654 |
+
{
|
655 |
+
fprintf(stderr, "Asserting on type %d\n",(int)src0t);
|
656 |
+
GGML_ASSERT(false && "not implemented");
|
657 |
+
}
|
658 |
+
};
|
659 |
+
|
660 |
+
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
|
661 |
+
[encoder setBuffer:id_src1 offset:offs_src1 atIndex:1];
|
662 |
+
[encoder setBuffer:id_dst offset:offs_dst atIndex:2];
|
663 |
+
[encoder setBytes:&ne00 length:sizeof(ne00) atIndex:3];
|
664 |
+
[encoder setBytes:&ne01 length:sizeof(ne01) atIndex:4];
|
665 |
+
[encoder setBytes:&nb00 length:sizeof(nb00) atIndex:5];
|
666 |
+
[encoder setBytes:&nb01 length:sizeof(nb01) atIndex:6];
|
667 |
+
[encoder setBytes:&nb02 length:sizeof(nb02) atIndex:7];
|
668 |
+
[encoder setBytes:&ne10 length:sizeof(ne10) atIndex:8];
|
669 |
+
[encoder setBytes:&ne11 length:sizeof(ne11) atIndex:9];
|
670 |
+
[encoder setBytes:&nb10 length:sizeof(nb10) atIndex:10];
|
671 |
+
[encoder setBytes:&nb11 length:sizeof(nb11) atIndex:11];
|
672 |
+
[encoder setBytes:&nb12 length:sizeof(nb12) atIndex:12];
|
673 |
+
[encoder setBytes:&ne0 length:sizeof(ne0) atIndex:13];
|
674 |
+
[encoder setBytes:&ne1 length:sizeof(ne1) atIndex:14];
|
675 |
+
|
676 |
+
if (src0t == GGML_TYPE_Q4_0 || src0t == GGML_TYPE_Q4_1) {
|
677 |
+
[encoder setThreadgroupMemoryLength:nth0*nth1*sizeof(float) atIndex:0];
|
678 |
+
[encoder dispatchThreadgroups:MTLSizeMake(ne01, ne11, 1) threadsPerThreadgroup:MTLSizeMake(nth0, nth1, 1)];
|
679 |
+
}
|
680 |
+
else if (src0t == GGML_TYPE_Q2_K ||
|
681 |
+
src0t == GGML_TYPE_Q3_K ||
|
682 |
+
src0t == GGML_TYPE_Q4_K ||
|
683 |
+
src0t == GGML_TYPE_Q5_K ||
|
684 |
+
src0t == GGML_TYPE_Q6_K) {
|
685 |
+
[encoder setThreadgroupMemoryLength:nth0*nth1*sizeof(float) atIndex:0];
|
686 |
+
[encoder dispatchThreadgroups:MTLSizeMake(ne01, 1, 1) threadsPerThreadgroup:MTLSizeMake(nth0, nth1, 1)];
|
687 |
+
} else {
|
688 |
+
[encoder setThreadgroupMemoryLength:nth0*sizeof(float) atIndex:0];
|
689 |
+
[encoder dispatchThreadgroups:MTLSizeMake(ne01, ne11, ne12) threadsPerThreadgroup:MTLSizeMake(nth0, nth1, 1)];
|
690 |
+
}
|
691 |
+
}
|
692 |
+
} break;
|
693 |
+
case GGML_OP_GET_ROWS:
|
694 |
+
{
|
695 |
+
if (encoder == nil) {
|
696 |
+
encoder = [command_buffer computeCommandEncoder];
|
697 |
+
}
|
698 |
+
|
699 |
+
switch (src0->type) {
|
700 |
+
case GGML_TYPE_F16: [encoder setComputePipelineState:ctx->pipeline_get_rows_f16]; break;
|
701 |
+
case GGML_TYPE_Q4_0: [encoder setComputePipelineState:ctx->pipeline_get_rows_q4_0]; break;
|
702 |
+
case GGML_TYPE_Q4_1: [encoder setComputePipelineState:ctx->pipeline_get_rows_q4_1]; break;
|
703 |
+
case GGML_TYPE_Q2_K: [encoder setComputePipelineState:ctx->pipeline_get_rows_q2_k]; break;
|
704 |
+
case GGML_TYPE_Q3_K: [encoder setComputePipelineState:ctx->pipeline_get_rows_q3_k]; break;
|
705 |
+
case GGML_TYPE_Q4_K: [encoder setComputePipelineState:ctx->pipeline_get_rows_q4_k]; break;
|
706 |
+
case GGML_TYPE_Q5_K: [encoder setComputePipelineState:ctx->pipeline_get_rows_q5_k]; break;
|
707 |
+
case GGML_TYPE_Q6_K: [encoder setComputePipelineState:ctx->pipeline_get_rows_q6_k]; break;
|
708 |
+
default: GGML_ASSERT(false && "not implemented");
|
709 |
+
}
|
710 |
+
|
711 |
+
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
|
712 |
+
[encoder setBuffer:id_src1 offset:offs_src1 atIndex:1];
|
713 |
+
[encoder setBuffer:id_dst offset:offs_dst atIndex:2];
|
714 |
+
[encoder setBytes:&(src0->ne[0]) length:sizeof( int64_t) atIndex:3];
|
715 |
+
[encoder setBytes:&(src0->nb[1]) length:sizeof(uint64_t) atIndex:4];
|
716 |
+
[encoder setBytes:&(dst->nb[1]) length:sizeof(uint64_t) atIndex:5];
|
717 |
+
|
718 |
+
const int64_t n = ggml_nelements(src1);
|
719 |
+
|
720 |
+
[encoder dispatchThreadgroups:MTLSizeMake(n, 1, 1) threadsPerThreadgroup:MTLSizeMake(1, 1, 1)];
|
721 |
+
} break;
|
722 |
+
case GGML_OP_RMS_NORM:
|
723 |
+
{
|
724 |
+
if (encoder == nil) {
|
725 |
+
encoder = [command_buffer computeCommandEncoder];
|
726 |
+
}
|
727 |
+
|
728 |
+
const float eps = 1e-6f;
|
729 |
+
|
730 |
+
const int nth = 256;
|
731 |
+
|
732 |
+
[encoder setComputePipelineState:ctx->pipeline_rms_norm];
|
733 |
+
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
|
734 |
+
[encoder setBuffer:id_dst offset:offs_dst atIndex:1];
|
735 |
+
[encoder setBytes:&ne00 length:sizeof( int64_t) atIndex:2];
|
736 |
+
[encoder setBytes:&nb01 length:sizeof(uint64_t) atIndex:3];
|
737 |
+
[encoder setBytes:&eps length:sizeof( float) atIndex:4];
|
738 |
+
[encoder setThreadgroupMemoryLength:nth*sizeof(float) atIndex:0];
|
739 |
+
|
740 |
+
const int64_t nrows = ggml_nrows(src0);
|
741 |
+
|
742 |
+
[encoder dispatchThreadgroups:MTLSizeMake(nrows, 1, 1) threadsPerThreadgroup:MTLSizeMake(nth, 1, 1)];
|
743 |
+
} break;
|
744 |
+
case GGML_OP_NORM:
|
745 |
+
{
|
746 |
+
if (encoder == nil) {
|
747 |
+
encoder = [command_buffer computeCommandEncoder];
|
748 |
+
}
|
749 |
+
|
750 |
+
const float eps = 1e-5f;
|
751 |
+
|
752 |
+
const int nth = 256;
|
753 |
+
|
754 |
+
[encoder setComputePipelineState:ctx->pipeline_norm];
|
755 |
+
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
|
756 |
+
[encoder setBuffer:id_dst offset:offs_dst atIndex:1];
|
757 |
+
[encoder setBytes:&ne00 length:sizeof( int64_t) atIndex:2];
|
758 |
+
[encoder setBytes:&nb01 length:sizeof(uint64_t) atIndex:3];
|
759 |
+
[encoder setBytes:&eps length:sizeof( float) atIndex:4];
|
760 |
+
[encoder setThreadgroupMemoryLength:nth*sizeof(float) atIndex:0];
|
761 |
+
|
762 |
+
const int64_t nrows = ggml_nrows(src0);
|
763 |
+
|
764 |
+
[encoder dispatchThreadgroups:MTLSizeMake(nrows, 1, 1) threadsPerThreadgroup:MTLSizeMake(nth, 1, 1)];
|
765 |
+
} break;
|
766 |
+
case GGML_OP_ALIBI:
|
767 |
+
{
|
768 |
+
GGML_ASSERT((src0t == GGML_TYPE_F32));
|
769 |
+
const int n_past = ((int32_t *) src1->data)[0];
|
770 |
+
const int n_head = ((int32_t *) src1->data)[1];
|
771 |
+
const float max_bias = ((float *) src1->data)[2];
|
772 |
+
if (__builtin_popcount(n_head) != 1) {
|
773 |
+
GGML_ASSERT(false && "only power-of-two n_head implemented");
|
774 |
+
}
|
775 |
+
const int n_heads_log2_floor = 1 << (int) floor(log2(n_head));
|
776 |
+
const float m0 = powf(2.0f, -(max_bias) / n_heads_log2_floor);
|
777 |
+
if (encoder == nil) {
|
778 |
+
encoder = [command_buffer computeCommandEncoder];
|
779 |
+
}
|
780 |
+
[encoder setComputePipelineState:ctx->pipeline_alibi_f32];
|
781 |
+
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
|
782 |
+
[encoder setBuffer:id_dst offset:offs_dst atIndex:1];
|
783 |
+
[encoder setBytes:&ne00 length:sizeof( int64_t) atIndex:2];
|
784 |
+
[encoder setBytes:&ne01 length:sizeof( int64_t) atIndex:3];
|
785 |
+
[encoder setBytes:&ne02 length:sizeof( int64_t) atIndex:4];
|
786 |
+
[encoder setBytes:&ne03 length:sizeof( int64_t) atIndex:5];
|
787 |
+
[encoder setBytes:&nb00 length:sizeof(uint64_t) atIndex:6];
|
788 |
+
[encoder setBytes:&nb01 length:sizeof(uint64_t) atIndex:7];
|
789 |
+
[encoder setBytes:&nb02 length:sizeof(uint64_t) atIndex:8];
|
790 |
+
[encoder setBytes:&nb03 length:sizeof(uint64_t) atIndex:9];
|
791 |
+
[encoder setBytes:&ne0 length:sizeof( int64_t) atIndex:10];
|
792 |
+
[encoder setBytes:&ne1 length:sizeof( int64_t) atIndex:11];
|
793 |
+
[encoder setBytes:&ne2 length:sizeof( int64_t) atIndex:12];
|
794 |
+
[encoder setBytes:&ne3 length:sizeof( int64_t) atIndex:13];
|
795 |
+
[encoder setBytes:&nb0 length:sizeof(uint64_t) atIndex:14];
|
796 |
+
[encoder setBytes:&nb1 length:sizeof(uint64_t) atIndex:15];
|
797 |
+
[encoder setBytes:&nb2 length:sizeof(uint64_t) atIndex:16];
|
798 |
+
[encoder setBytes:&nb3 length:sizeof(uint64_t) atIndex:17];
|
799 |
+
[encoder setBytes:&m0 length:sizeof( float) atIndex:18];
|
800 |
+
const int nth = 32;
|
801 |
+
[encoder dispatchThreadgroups:MTLSizeMake(ne01, ne02, ne03) threadsPerThreadgroup:MTLSizeMake(nth, 1, 1)];
|
802 |
+
} break;
|
803 |
+
case GGML_OP_ROPE:
|
804 |
+
{
|
805 |
+
if (encoder == nil) {
|
806 |
+
encoder = [command_buffer computeCommandEncoder];
|
807 |
+
}
|
808 |
+
|
809 |
+
const int n_dims = ((int32_t *) src1->data)[1];
|
810 |
+
const int mode = ((int32_t *) src1->data)[2];
|
811 |
+
|
812 |
+
const int n_past = ((int32_t *)(src1->data))[0];
|
813 |
+
|
814 |
+
[encoder setComputePipelineState:ctx->pipeline_rope];
|
815 |
+
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
|
816 |
+
[encoder setBuffer:id_dst offset:offs_dst atIndex:1];
|
817 |
+
[encoder setBytes:&ne00 length:sizeof( int64_t) atIndex:2];
|
818 |
+
[encoder setBytes:&ne01 length:sizeof( int64_t) atIndex:3];
|
819 |
+
[encoder setBytes:&ne02 length:sizeof( int64_t) atIndex:4];
|
820 |
+
[encoder setBytes:&ne03 length:sizeof( int64_t) atIndex:5];
|
821 |
+
[encoder setBytes:&nb00 length:sizeof(uint64_t) atIndex:6];
|
822 |
+
[encoder setBytes:&nb01 length:sizeof(uint64_t) atIndex:7];
|
823 |
+
[encoder setBytes:&nb02 length:sizeof(uint64_t) atIndex:8];
|
824 |
+
[encoder setBytes:&nb03 length:sizeof(uint64_t) atIndex:9];
|
825 |
+
[encoder setBytes:&ne0 length:sizeof( int64_t) atIndex:10];
|
826 |
+
[encoder setBytes:&ne1 length:sizeof( int64_t) atIndex:11];
|
827 |
+
[encoder setBytes:&ne2 length:sizeof( int64_t) atIndex:12];
|
828 |
+
[encoder setBytes:&ne3 length:sizeof( int64_t) atIndex:13];
|
829 |
+
[encoder setBytes:&nb0 length:sizeof(uint64_t) atIndex:14];
|
830 |
+
[encoder setBytes:&nb1 length:sizeof(uint64_t) atIndex:15];
|
831 |
+
[encoder setBytes:&nb2 length:sizeof(uint64_t) atIndex:16];
|
832 |
+
[encoder setBytes:&nb3 length:sizeof(uint64_t) atIndex:17];
|
833 |
+
[encoder setBytes:&n_past length:sizeof( int) atIndex:18];
|
834 |
+
[encoder setBytes:&n_dims length:sizeof( int) atIndex:19];
|
835 |
+
[encoder setBytes:&mode length:sizeof( int) atIndex:20];
|
836 |
+
|
837 |
+
[encoder dispatchThreadgroups:MTLSizeMake(ne01, ne02, ne03) threadsPerThreadgroup:MTLSizeMake(1, 1, 1)];
|
838 |
+
} break;
|
839 |
+
case GGML_OP_CPY:
|
840 |
+
{
|
841 |
+
if (encoder == nil) {
|
842 |
+
encoder = [command_buffer computeCommandEncoder];
|
843 |
+
}
|
844 |
+
|
845 |
+
const int nth = 32;
|
846 |
+
|
847 |
+
switch (src0t) {
|
848 |
+
case GGML_TYPE_F32:
|
849 |
+
{
|
850 |
+
switch (dstt) {
|
851 |
+
case GGML_TYPE_F16: [encoder setComputePipelineState:ctx->pipeline_cpy_f32_f16]; break;
|
852 |
+
case GGML_TYPE_F32: [encoder setComputePipelineState:ctx->pipeline_cpy_f32_f32]; break;
|
853 |
+
default: GGML_ASSERT(false && "not implemented");
|
854 |
+
};
|
855 |
+
} break;
|
856 |
+
case GGML_TYPE_F16:
|
857 |
+
{
|
858 |
+
switch (dstt) {
|
859 |
+
case GGML_TYPE_F16: [encoder setComputePipelineState:ctx->pipeline_cpy_f16_f16]; break;
|
860 |
+
case GGML_TYPE_F32: GGML_ASSERT(false && "cpy_f16_f32 not implemented"); break;
|
861 |
+
default: GGML_ASSERT(false && "not implemented");
|
862 |
+
};
|
863 |
+
} break;
|
864 |
+
default: GGML_ASSERT(false && "not implemented");
|
865 |
+
}
|
866 |
+
|
867 |
+
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
|
868 |
+
[encoder setBuffer:id_dst offset:offs_dst atIndex:1];
|
869 |
+
[encoder setBytes:&ne00 length:sizeof( int64_t) atIndex:2];
|
870 |
+
[encoder setBytes:&ne01 length:sizeof( int64_t) atIndex:3];
|
871 |
+
[encoder setBytes:&ne02 length:sizeof( int64_t) atIndex:4];
|
872 |
+
[encoder setBytes:&ne03 length:sizeof( int64_t) atIndex:5];
|
873 |
+
[encoder setBytes:&nb00 length:sizeof(uint64_t) atIndex:6];
|
874 |
+
[encoder setBytes:&nb01 length:sizeof(uint64_t) atIndex:7];
|
875 |
+
[encoder setBytes:&nb02 length:sizeof(uint64_t) atIndex:8];
|
876 |
+
[encoder setBytes:&nb03 length:sizeof(uint64_t) atIndex:9];
|
877 |
+
[encoder setBytes:&ne0 length:sizeof( int64_t) atIndex:10];
|
878 |
+
[encoder setBytes:&ne1 length:sizeof( int64_t) atIndex:11];
|
879 |
+
[encoder setBytes:&ne2 length:sizeof( int64_t) atIndex:12];
|
880 |
+
[encoder setBytes:&ne3 length:sizeof( int64_t) atIndex:13];
|
881 |
+
[encoder setBytes:&nb0 length:sizeof(uint64_t) atIndex:14];
|
882 |
+
[encoder setBytes:&nb1 length:sizeof(uint64_t) atIndex:15];
|
883 |
+
[encoder setBytes:&nb2 length:sizeof(uint64_t) atIndex:16];
|
884 |
+
[encoder setBytes:&nb3 length:sizeof(uint64_t) atIndex:17];
|
885 |
+
|
886 |
+
[encoder dispatchThreadgroups:MTLSizeMake(ne01, ne02, ne03) threadsPerThreadgroup:MTLSizeMake(nth, 1, 1)];
|
887 |
+
} break;
|
888 |
+
default:
|
889 |
+
fprintf(stderr, "%s: node %3d, op = %8s not implemented\n", __func__, i, ggml_op_name(dst->op));
|
890 |
+
GGML_ASSERT(false);
|
891 |
+
}
|
892 |
+
}
|
893 |
+
|
894 |
+
if (encoder != nil) {
|
895 |
+
[encoder endEncoding];
|
896 |
+
encoder = nil;
|
897 |
+
}
|
898 |
+
|
899 |
+
[command_buffer commit];
|
900 |
+
});
|
901 |
}
|
902 |
+
|
903 |
+
// wait for all threads to finish
|
904 |
+
dispatch_barrier_sync(queue, ^{});
|
905 |
+
|
906 |
+
[command_buffers[n_cb - 1] waitUntilCompleted];
|
907 |
}
|
ggml-metal.metal
CHANGED
@@ -256,6 +256,72 @@ kernel void kernel_get_rows_q4_1(
|
|
256 |
(device float *) ((device char *) dst + i*nb1), ne00);
|
257 |
}
|
258 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
259 |
kernel void kernel_rms_norm(
|
260 |
device const void * src0,
|
261 |
device float * dst,
|
@@ -485,6 +551,48 @@ kernel void kernel_mul_mat_f16_f32(
|
|
485 |
}
|
486 |
}
|
487 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
488 |
kernel void kernel_rope(
|
489 |
device const void * src0,
|
490 |
device float * dst,
|
@@ -540,6 +648,47 @@ kernel void kernel_rope(
|
|
540 |
}
|
541 |
}
|
542 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
543 |
kernel void kernel_cpy_f32_f16(
|
544 |
device const float * src0,
|
545 |
device half * dst,
|
|
|
256 |
(device float *) ((device char *) dst + i*nb1), ne00);
|
257 |
}
|
258 |
|
259 |
+
kernel void kernel_norm(
|
260 |
+
device const void * src0,
|
261 |
+
device float * dst,
|
262 |
+
constant int64_t & ne00,
|
263 |
+
constant uint64_t & nb01,
|
264 |
+
constant float & eps,
|
265 |
+
threadgroup float * sum [[threadgroup(0)]],
|
266 |
+
uint tgpig[[threadgroup_position_in_grid]],
|
267 |
+
uint tpitg[[thread_position_in_threadgroup]],
|
268 |
+
uint ntg[[threads_per_threadgroup]]) {
|
269 |
+
device const float * x = (device const float *) ((device const char *) src0 + tgpig*nb01);
|
270 |
+
// MEAN
|
271 |
+
// parallel sum
|
272 |
+
sum[tpitg] = 0.0f;
|
273 |
+
for (int i00 = tpitg; i00 < ne00; i00 += ntg) {
|
274 |
+
sum[tpitg] += x[i00];
|
275 |
+
}
|
276 |
+
// reduce
|
277 |
+
threadgroup_barrier(mem_flags::mem_threadgroup);
|
278 |
+
for (uint i = ntg/2; i > 0; i /= 2) {
|
279 |
+
if (tpitg < i) {
|
280 |
+
sum[tpitg] += sum[tpitg + i];
|
281 |
+
}
|
282 |
+
threadgroup_barrier(mem_flags::mem_threadgroup);
|
283 |
+
}
|
284 |
+
// broadcast
|
285 |
+
if (tpitg == 0) {
|
286 |
+
sum[0] /= ne00;
|
287 |
+
}
|
288 |
+
threadgroup_barrier(mem_flags::mem_threadgroup);
|
289 |
+
const float mean = sum[0];
|
290 |
+
|
291 |
+
// recenter
|
292 |
+
device float * y = dst + tgpig*ne00;
|
293 |
+
for (int i00 = tpitg; i00 < ne00; i00 += ntg) {
|
294 |
+
y[i00] = x[i00] - mean;
|
295 |
+
}
|
296 |
+
|
297 |
+
// VARIANCE
|
298 |
+
// parallel sum
|
299 |
+
sum[tpitg] = 0.0f;
|
300 |
+
for (int i00 = tpitg; i00 < ne00; i00 += ntg) {
|
301 |
+
sum[tpitg] += y[i00] * y[i00];
|
302 |
+
}
|
303 |
+
// reduce
|
304 |
+
threadgroup_barrier(mem_flags::mem_threadgroup);
|
305 |
+
for (uint i = ntg/2; i > 0; i /= 2) {
|
306 |
+
if (tpitg < i) {
|
307 |
+
sum[tpitg] += sum[tpitg + i];
|
308 |
+
}
|
309 |
+
threadgroup_barrier(mem_flags::mem_threadgroup);
|
310 |
+
}
|
311 |
+
// broadcast
|
312 |
+
if (tpitg == 0) {
|
313 |
+
sum[0] /= ne00;
|
314 |
+
}
|
315 |
+
threadgroup_barrier(mem_flags::mem_threadgroup);
|
316 |
+
const float variance = sum[0];
|
317 |
+
|
318 |
+
const float scale = 1.0f/sqrt(variance + eps);
|
319 |
+
for (int i00 = tpitg; i00 < ne00; i00 += ntg) {
|
320 |
+
y[i00] = y[i00] * scale;
|
321 |
+
}
|
322 |
+
}
|
323 |
+
|
324 |
+
|
325 |
kernel void kernel_rms_norm(
|
326 |
device const void * src0,
|
327 |
device float * dst,
|
|
|
551 |
}
|
552 |
}
|
553 |
|
554 |
+
kernel void kernel_alibi_f32(
|
555 |
+
device const float * src0,
|
556 |
+
device float * dst,
|
557 |
+
constant int64_t & ne00,
|
558 |
+
constant int64_t & ne01,
|
559 |
+
constant int64_t & ne02,
|
560 |
+
constant int64_t & ne03,
|
561 |
+
constant uint64_t & nb00,
|
562 |
+
constant uint64_t & nb01,
|
563 |
+
constant uint64_t & nb02,
|
564 |
+
constant uint64_t & nb03,
|
565 |
+
constant int64_t & ne0,
|
566 |
+
constant int64_t & ne1,
|
567 |
+
constant int64_t & ne2,
|
568 |
+
constant int64_t & ne3,
|
569 |
+
constant uint64_t & nb0,
|
570 |
+
constant uint64_t & nb1,
|
571 |
+
constant uint64_t & nb2,
|
572 |
+
constant uint64_t & nb3,
|
573 |
+
constant float & m0,
|
574 |
+
uint3 tgpig[[threadgroup_position_in_grid]],
|
575 |
+
uint3 tpitg[[thread_position_in_threadgroup]],
|
576 |
+
uint3 ntg[[threads_per_threadgroup]]) {
|
577 |
+
const int64_t i03 = tgpig[2];
|
578 |
+
const int64_t i02 = tgpig[1];
|
579 |
+
const int64_t i01 = tgpig[0];
|
580 |
+
|
581 |
+
const int64_t n = i03*ne02*ne01*ne00 + i02*ne01*ne00 + i01*ne00;
|
582 |
+
|
583 |
+
const int64_t i3 = n / (ne2*ne1*ne0);
|
584 |
+
const int64_t i2 = (n - i3*ne2*ne1*ne0) / (ne1*ne0);
|
585 |
+
const int64_t i1 = (n - i3*ne2*ne1*ne0 - i2*ne1*ne0) / ne0;
|
586 |
+
const int64_t i0 = (n - i3*ne2*ne1*ne0 - i2*ne1*ne0 - i1*ne0);
|
587 |
+
|
588 |
+
device float * dst_data = (device float *) ((device char *) dst + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
|
589 |
+
float m_k = pow(m0, i2 + 1);
|
590 |
+
for (int64_t i00 = tpitg.x; i00 < ne00; i00 += ntg.x) {
|
591 |
+
device const float * src = (device float *)((device char *) src0 + i03*nb03 + i02*nb02 + i01*nb01 + i00*nb00);
|
592 |
+
dst_data[i00] = src[0] + m_k * (i00 - ne00 + 1);
|
593 |
+
}
|
594 |
+
}
|
595 |
+
|
596 |
kernel void kernel_rope(
|
597 |
device const void * src0,
|
598 |
device float * dst,
|
|
|
648 |
}
|
649 |
}
|
650 |
|
651 |
+
kernel void kernel_cpy_f16_f16(
|
652 |
+
device const half * src0,
|
653 |
+
device half * dst,
|
654 |
+
constant int64_t & ne00,
|
655 |
+
constant int64_t & ne01,
|
656 |
+
constant int64_t & ne02,
|
657 |
+
constant int64_t & ne03,
|
658 |
+
constant uint64_t & nb00,
|
659 |
+
constant uint64_t & nb01,
|
660 |
+
constant uint64_t & nb02,
|
661 |
+
constant uint64_t & nb03,
|
662 |
+
constant int64_t & ne0,
|
663 |
+
constant int64_t & ne1,
|
664 |
+
constant int64_t & ne2,
|
665 |
+
constant int64_t & ne3,
|
666 |
+
constant uint64_t & nb0,
|
667 |
+
constant uint64_t & nb1,
|
668 |
+
constant uint64_t & nb2,
|
669 |
+
constant uint64_t & nb3,
|
670 |
+
uint3 tgpig[[threadgroup_position_in_grid]],
|
671 |
+
uint3 tpitg[[thread_position_in_threadgroup]],
|
672 |
+
uint3 ntg[[threads_per_threadgroup]]) {
|
673 |
+
const int64_t i03 = tgpig[2];
|
674 |
+
const int64_t i02 = tgpig[1];
|
675 |
+
const int64_t i01 = tgpig[0];
|
676 |
+
|
677 |
+
const int64_t n = i03*ne02*ne01*ne00 + i02*ne01*ne00 + i01*ne00;
|
678 |
+
|
679 |
+
const int64_t i3 = n / (ne2*ne1*ne0);
|
680 |
+
const int64_t i2 = (n - i3*ne2*ne1*ne0) / (ne1*ne0);
|
681 |
+
const int64_t i1 = (n - i3*ne2*ne1*ne0 - i2*ne1*ne0) / ne0;
|
682 |
+
const int64_t i0 = (n - i3*ne2*ne1*ne0 - i2*ne1*ne0 - i1*ne0);
|
683 |
+
|
684 |
+
device half * dst_data = (device half *) ((device char *) dst + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
|
685 |
+
|
686 |
+
for (int64_t i00 = tpitg.x; i00 < ne00; i00 += ntg.x) {
|
687 |
+
device const half * src = (device half *)((device char *) src0 + i03*nb03 + i02*nb02 + i01*nb01 + i00*nb00);
|
688 |
+
dst_data[i00] = src[0];
|
689 |
+
}
|
690 |
+
}
|
691 |
+
|
692 |
kernel void kernel_cpy_f32_f16(
|
693 |
device const float * src0,
|
694 |
device half * dst,
|
ggml.c
CHANGED
@@ -35,6 +35,12 @@
|
|
35 |
#define static_assert(cond, msg) struct global_scope_noop_trick
|
36 |
#endif
|
37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
#if defined(_WIN32)
|
39 |
|
40 |
#include <windows.h>
|
@@ -3939,6 +3945,12 @@ bool ggml_is_contiguous(const struct ggml_tensor * tensor) {
|
|
3939 |
tensor->nb[3] == tensor->nb[2]*tensor->ne[2];
|
3940 |
}
|
3941 |
|
|
|
|
|
|
|
|
|
|
|
|
|
3942 |
static inline bool ggml_is_padded_1d(const struct ggml_tensor * tensor) {
|
3943 |
static_assert(GGML_MAX_DIMS == 4, "GGML_MAX_DIMS is not 4 - update this function");
|
3944 |
|
|
|
35 |
#define static_assert(cond, msg) struct global_scope_noop_trick
|
36 |
#endif
|
37 |
|
38 |
+
#if defined(_MSC_VER)
|
39 |
+
// disable "possible loss of data" to avoid hundreds of casts
|
40 |
+
// we should just be careful :)
|
41 |
+
#pragma warning(disable: 4244 4267)
|
42 |
+
#endif
|
43 |
+
|
44 |
#if defined(_WIN32)
|
45 |
|
46 |
#include <windows.h>
|
|
|
3945 |
tensor->nb[3] == tensor->nb[2]*tensor->ne[2];
|
3946 |
}
|
3947 |
|
3948 |
+
bool ggml_is_permuted(const struct ggml_tensor * tensor) {
|
3949 |
+
static_assert(GGML_MAX_DIMS == 4, "GGML_MAX_DIMS is not 4 - update this function");
|
3950 |
+
|
3951 |
+
return tensor->nb[0] > tensor->nb[1] || tensor->nb[1] > tensor->nb[2] || tensor->nb[2] > tensor->nb[3];
|
3952 |
+
}
|
3953 |
+
|
3954 |
static inline bool ggml_is_padded_1d(const struct ggml_tensor * tensor) {
|
3955 |
static_assert(GGML_MAX_DIMS == 4, "GGML_MAX_DIMS is not 4 - update this function");
|
3956 |
|
ggml.h
CHANGED
@@ -485,6 +485,7 @@ extern "C" {
|
|
485 |
|
486 |
GGML_API bool ggml_is_transposed(const struct ggml_tensor * tensor);
|
487 |
GGML_API bool ggml_is_contiguous(const struct ggml_tensor * tensor);
|
|
|
488 |
|
489 |
// use this to compute the memory overhead of a tensor
|
490 |
GGML_API size_t ggml_tensor_overhead(void);
|
|
|
485 |
|
486 |
GGML_API bool ggml_is_transposed(const struct ggml_tensor * tensor);
|
487 |
GGML_API bool ggml_is_contiguous(const struct ggml_tensor * tensor);
|
488 |
+
GGML_API bool ggml_is_permuted (const struct ggml_tensor * tensor);
|
489 |
|
490 |
// use this to compute the memory overhead of a tensor
|
491 |
GGML_API size_t ggml_tensor_overhead(void);
|
gpttype_adapter.cpp
CHANGED
@@ -1173,6 +1173,16 @@ generation_outputs gpttype_generate(const generation_inputs inputs, generation_o
|
|
1173 |
int topid = std::min_element(logits.begin(),logits.end())-logits.begin();
|
1174 |
logits[eosID] = (logits[topid] < 0 ? logits[topid] : 0);
|
1175 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1176 |
}
|
1177 |
|
1178 |
// set the logit of the eos token (0) to minimum to avoid sampling it
|
@@ -1280,7 +1290,8 @@ generation_outputs gpttype_generate(const generation_inputs inputs, generation_o
|
|
1280 |
float pt1 = (time1*1000.0/(embd_inp.size()==0?1:embd_inp.size()));
|
1281 |
int realnpredict = params.n_predict-stopper_unused_tokens;
|
1282 |
float pt2 = (time2*1000.0/(realnpredict==0?1:realnpredict));
|
1283 |
-
|
|
|
1284 |
fflush(stdout);
|
1285 |
output.status = 1;
|
1286 |
generation_finished = true;
|
|
|
1173 |
int topid = std::min_element(logits.begin(),logits.end())-logits.begin();
|
1174 |
logits[eosID] = (logits[topid] < 0 ? logits[topid] : 0);
|
1175 |
}
|
1176 |
+
else
|
1177 |
+
{
|
1178 |
+
//special case, starcoder models use ID 0 for EOS
|
1179 |
+
if (file_format == FileFormat::GPT2_3 || file_format == FileFormat::GPT2_4)
|
1180 |
+
{
|
1181 |
+
eosID = 0;
|
1182 |
+
int topid = std::min_element(logits.begin(), logits.end()) - logits.begin();
|
1183 |
+
logits[eosID] = (logits[topid] < 0 ? logits[topid] : 0);
|
1184 |
+
}
|
1185 |
+
}
|
1186 |
}
|
1187 |
|
1188 |
// set the logit of the eos token (0) to minimum to avoid sampling it
|
|
|
1290 |
float pt1 = (time1*1000.0/(embd_inp.size()==0?1:embd_inp.size()));
|
1291 |
int realnpredict = params.n_predict-stopper_unused_tokens;
|
1292 |
float pt2 = (time2*1000.0/(realnpredict==0?1:realnpredict));
|
1293 |
+
float tokens_per_second = (realnpredict == 0 ? 0 : realnpredict / (time1 + time2));
|
1294 |
+
printf("\nTime Taken - Processing:%.1fs (%.0fms/T), Generation:%.1fs (%.0fms/T), Total:%.1fs (%.1fT/s)", time1, pt1, time2, pt2, (time1 + time2), tokens_per_second);
|
1295 |
fflush(stdout);
|
1296 |
output.status = 1;
|
1297 |
generation_finished = true;
|
klite.embd
CHANGED
The diff for this file is too large to render.
See raw diff
|
|
koboldcpp.py
CHANGED
@@ -224,7 +224,7 @@ maxctx = 2048
|
|
224 |
maxlen = 256
|
225 |
modelbusy = False
|
226 |
defaultport = 5001
|
227 |
-
KcppVersion = "1.
|
228 |
|
229 |
class ServerRequestHandler(http.server.SimpleHTTPRequestHandler):
|
230 |
sys_version = ""
|
@@ -415,6 +415,7 @@ class ServerRequestHandler(http.server.SimpleHTTPRequestHandler):
|
|
415 |
self.end_headers()
|
416 |
self.wfile.write(json.dumps({"success": ("true" if ag else "false")}).encode())
|
417 |
print("Generation Aborted")
|
|
|
418 |
return
|
419 |
|
420 |
if self.path.endswith('/api/extra/generate/check'):
|
|
|
224 |
maxlen = 256
|
225 |
modelbusy = False
|
226 |
defaultport = 5001
|
227 |
+
KcppVersion = "1.31"
|
228 |
|
229 |
class ServerRequestHandler(http.server.SimpleHTTPRequestHandler):
|
230 |
sys_version = ""
|
|
|
415 |
self.end_headers()
|
416 |
self.wfile.write(json.dumps({"success": ("true" if ag else "false")}).encode())
|
417 |
print("Generation Aborted")
|
418 |
+
modelbusy = False
|
419 |
return
|
420 |
|
421 |
if self.path.endswith('/api/extra/generate/check'):
|
llama.cpp
CHANGED
@@ -40,6 +40,10 @@
|
|
40 |
#include <sstream>
|
41 |
#include <numeric>
|
42 |
|
|
|
|
|
|
|
|
|
43 |
#define LLAMA_USE_SCRATCH
|
44 |
#define LLAMA_MAX_SCRATCH_BUFFERS 16
|
45 |
|
@@ -165,6 +169,11 @@ struct llama_kv_cache {
|
|
165 |
if (ctx) {
|
166 |
ggml_free(ctx);
|
167 |
}
|
|
|
|
|
|
|
|
|
|
|
168 |
}
|
169 |
};
|
170 |
|
@@ -210,6 +219,7 @@ struct llama_model {
|
|
210 |
for (size_t i = 0; i < tensors_by_name.size(); ++i) {
|
211 |
ggml_cuda_free_data(tensors_by_name[i].second);
|
212 |
}
|
|
|
213 |
#elif defined(GGML_USE_CLBLAST)
|
214 |
for (size_t i = 0; i < tensors_by_name.size(); ++i) {
|
215 |
ggml_cl_free_data(tensors_by_name[i].second);
|
@@ -867,7 +877,8 @@ static bool kv_cache_init(
|
|
867 |
const struct llama_hparams & hparams,
|
868 |
struct llama_kv_cache & cache,
|
869 |
ggml_type wtype,
|
870 |
-
int n_ctx
|
|
|
871 |
const int n_embd = hparams.n_embd;
|
872 |
const int n_layer = hparams.n_layer;
|
873 |
|
@@ -893,6 +904,15 @@ static bool kv_cache_init(
|
|
893 |
ggml_set_name(cache.k, "cache_k");
|
894 |
ggml_set_name(cache.v, "cache_v");
|
895 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
896 |
return true;
|
897 |
}
|
898 |
|
@@ -903,6 +923,7 @@ struct llama_context_params llama_context_default_params() {
|
|
903 |
/*.gpu_layers =*/ 0,
|
904 |
/*.main_gpu =*/ 0,
|
905 |
/*.tensor_split =*/ {0},
|
|
|
906 |
/*.seed =*/ -1,
|
907 |
/*.f16_kv =*/ true,
|
908 |
/*.logits_all =*/ false,
|
@@ -1011,6 +1032,7 @@ static void llama_model_load_internal(
|
|
1011 |
int n_gpu_layers,
|
1012 |
int main_gpu,
|
1013 |
const float * tensor_split,
|
|
|
1014 |
ggml_type memory_type,
|
1015 |
bool use_mmap,
|
1016 |
bool use_mlock,
|
@@ -1137,18 +1159,34 @@ static void llama_model_load_internal(
|
|
1137 |
ml->ggml_ctx = ctx;
|
1138 |
|
1139 |
model.tok_embeddings = ml->get_tensor("tok_embeddings.weight", {n_embd, n_vocab}, GGML_BACKEND_CPU);
|
1140 |
-
model.norm = ml->get_tensor("norm.weight", {n_embd}, GGML_BACKEND_CPU);
|
1141 |
|
1142 |
// "output" tensor
|
1143 |
{
|
|
|
1144 |
ggml_backend backend_output;
|
1145 |
if (n_gpu_layers > int(n_layer)) { // NOLINT
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1146 |
backend_output = LLAMA_BACKEND_OFFLOAD_SPLIT;
|
1147 |
} else {
|
|
|
1148 |
backend_output = GGML_BACKEND_CPU;
|
1149 |
}
|
1150 |
|
|
|
1151 |
model.output = ml->get_tensor("output.weight", {n_embd, n_vocab}, backend_output);
|
|
|
|
|
|
|
|
|
|
|
|
|
1152 |
}
|
1153 |
|
1154 |
const int i_gpu_start = n_layer - n_gpu_layers;
|
@@ -1208,22 +1246,47 @@ static void llama_model_load_internal(
|
|
1208 |
(void) vram_scratch;
|
1209 |
(void) n_batch;
|
1210 |
#ifdef GGML_USE_CUBLAS
|
1211 |
-
|
1212 |
-
|
1213 |
-
|
1214 |
-
|
1215 |
-
|
|
|
|
|
|
|
|
|
|
|
1216 |
}
|
1217 |
#endif // GGML_USE_CUBLAS
|
1218 |
#if defined(GGML_USE_CUBLAS) || defined(GGML_USE_CLBLAST)
|
1219 |
const int n_gpu = std::min(n_gpu_layers, int(hparams.n_layer));
|
1220 |
|
1221 |
-
fprintf(stderr, "%s: offloading %d layers to GPU\n", __func__, n_gpu);
|
1222 |
if (n_gpu_layers > (int) hparams.n_layer) {
|
1223 |
-
fprintf(stderr, "%s: offloading
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1224 |
}
|
|
|
|
|
|
|
1225 |
fprintf(stderr, "%s: total VRAM used: %zu MB\n",
|
1226 |
-
__func__, (vram_weights + vram_scratch + MB - 1) / MB); // round up
|
1227 |
#else
|
1228 |
(void) n_gpu_layers;
|
1229 |
#endif
|
@@ -1262,6 +1325,7 @@ static bool llama_model_load(
|
|
1262 |
int n_gpu_layers,
|
1263 |
int main_gpu,
|
1264 |
float * tensor_split,
|
|
|
1265 |
ggml_type memory_type,
|
1266 |
bool use_mmap,
|
1267 |
bool use_mlock,
|
@@ -1269,7 +1333,7 @@ static bool llama_model_load(
|
|
1269 |
llama_progress_callback progress_callback,
|
1270 |
void *progress_callback_user_data) {
|
1271 |
try {
|
1272 |
-
llama_model_load_internal(fname, lctx, n_ctx, n_batch, n_gpu_layers, main_gpu, tensor_split, memory_type,
|
1273 |
use_mmap, use_mlock, vocab_only, progress_callback, progress_callback_user_data);
|
1274 |
return true;
|
1275 |
} catch (const std::exception & err) {
|
@@ -1345,12 +1409,33 @@ static bool llama_eval_internal(
|
|
1345 |
const int i_gpu_start = n_layer - n_gpu_layers;
|
1346 |
(void) i_gpu_start;
|
1347 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1348 |
for (int il = 0; il < n_layer; ++il) {
|
1349 |
offload_func_t offload_func = llama_nop;
|
1350 |
|
1351 |
#ifdef GGML_USE_CUBLAS
|
1352 |
if (il >= i_gpu_start) {
|
1353 |
-
offload_func = ggml_cuda_assign_buffers;
|
1354 |
}
|
1355 |
#endif // GGML_USE_CUBLAS
|
1356 |
|
@@ -1373,31 +1458,42 @@ static bool llama_eval_internal(
|
|
1373 |
// self-attention
|
1374 |
{
|
1375 |
// compute Q and K and RoPE them
|
1376 |
-
struct ggml_tensor * tmpq = ggml_mul_mat(ctx0, model.layers[il].wq, cur);
|
1377 |
-
// offload_func(tmpq);
|
1378 |
-
ggml_set_name(tmpq, "tmpq");
|
1379 |
-
|
1380 |
struct ggml_tensor * tmpk = ggml_mul_mat(ctx0, model.layers[il].wk, cur);
|
1381 |
-
|
1382 |
ggml_set_name(tmpk, "tmpk");
|
1383 |
|
|
|
|
|
|
|
|
|
1384 |
struct ggml_tensor * Kcur = ggml_rope_inplace(ctx0, ggml_reshape_3d(ctx0, tmpk, n_embd/n_head, n_head, N), n_past, n_rot, 0);
|
|
|
1385 |
ggml_set_name(Kcur, "Kcur");
|
1386 |
|
1387 |
struct ggml_tensor * Qcur = ggml_rope_inplace(ctx0, ggml_reshape_3d(ctx0, tmpq, n_embd/n_head, n_head, N), n_past, n_rot, 0);
|
|
|
1388 |
ggml_set_name(Qcur, "Qcur");
|
1389 |
|
1390 |
// store key and value to memory
|
1391 |
{
|
1392 |
// compute the transposed [N, n_embd] V matrix
|
1393 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1394 |
ggml_set_name(Vcur, "Vcur");
|
1395 |
|
1396 |
struct ggml_tensor * k = ggml_view_1d(ctx0, kv_self.k, N*n_embd, (ggml_element_size(kv_self.k)*n_embd)*(il*n_ctx + n_past));
|
|
|
1397 |
ggml_set_name(k, "k");
|
|
|
1398 |
struct ggml_tensor * v = ggml_view_2d(ctx0, kv_self.v, N, n_embd,
|
1399 |
( n_ctx)*ggml_element_size(kv_self.v),
|
1400 |
(il*n_ctx)*ggml_element_size(kv_self.v)*n_embd + n_past*ggml_element_size(kv_self.v));
|
|
|
1401 |
ggml_set_name(v, "v");
|
1402 |
|
1403 |
// important: storing RoPE-ed version of K in the KV cache!
|
@@ -1409,6 +1505,7 @@ static bool llama_eval_internal(
|
|
1409 |
ggml_permute(ctx0,
|
1410 |
Qcur,
|
1411 |
0, 2, 1, 3);
|
|
|
1412 |
ggml_set_name(Q, "Q");
|
1413 |
|
1414 |
struct ggml_tensor * K =
|
@@ -1417,10 +1514,12 @@ static bool llama_eval_internal(
|
|
1417 |
ggml_view_1d(ctx0, kv_self.k, (n_past + N)*n_embd, il*n_ctx*ggml_element_size(kv_self.k)*n_embd),
|
1418 |
n_embd/n_head, n_head, n_past + N),
|
1419 |
0, 2, 1, 3);
|
|
|
1420 |
ggml_set_name(K, "K");
|
1421 |
|
1422 |
// K * Q
|
1423 |
struct ggml_tensor * KQ = ggml_mul_mat(ctx0, K, Q);
|
|
|
1424 |
ggml_set_name(KQ, "KQ");
|
1425 |
|
1426 |
// KQ_scaled = KQ / sqrt(n_embd/n_head)
|
@@ -1429,14 +1528,17 @@ static bool llama_eval_internal(
|
|
1429 |
|
1430 |
// KQ_scaled shape [n_past + N, N, n_head, 1]
|
1431 |
struct ggml_tensor * KQ_scaled = ggml_scale_inplace(ctx0, KQ, KQ_scale);
|
|
|
1432 |
ggml_set_name(KQ_scaled, "KQ_scaled");
|
1433 |
|
1434 |
// KQ_masked = mask_past(KQ_scaled)
|
1435 |
struct ggml_tensor * KQ_masked = ggml_diag_mask_inf_inplace(ctx0, KQ_scaled, n_past);
|
|
|
1436 |
ggml_set_name(KQ_masked, "KQ_masked");
|
1437 |
|
1438 |
// KQ = soft_max(KQ_masked)
|
1439 |
struct ggml_tensor * KQ_soft_max = ggml_soft_max_inplace(ctx0, KQ_masked);
|
|
|
1440 |
ggml_set_name(KQ_soft_max, "KQ_soft_max");
|
1441 |
|
1442 |
// split cached V into n_head heads
|
@@ -1446,10 +1548,12 @@ static bool llama_eval_internal(
|
|
1446 |
n_ctx*ggml_element_size(kv_self.v),
|
1447 |
n_ctx*ggml_element_size(kv_self.v)*n_embd/n_head,
|
1448 |
il*n_ctx*ggml_element_size(kv_self.v)*n_embd);
|
|
|
1449 |
ggml_set_name(V, "V");
|
1450 |
|
1451 |
#if 1
|
1452 |
struct ggml_tensor * KQV = ggml_mul_mat(ctx0, V, KQ_soft_max);
|
|
|
1453 |
ggml_set_name(KQV, "KQV");
|
1454 |
#else
|
1455 |
// make V contiguous in memory to speed up the matmul, however we waste time on the copy
|
@@ -1461,12 +1565,14 @@ static bool llama_eval_internal(
|
|
1461 |
|
1462 |
// KQV_merged = KQV.permute(0, 2, 1, 3)
|
1463 |
struct ggml_tensor * KQV_merged = ggml_permute(ctx0, KQV, 0, 2, 1, 3);
|
|
|
1464 |
ggml_set_name(KQV_merged, "KQV_merged");
|
1465 |
|
1466 |
// cur = KQV_merged.contiguous().view(n_embd, N)
|
1467 |
cur = ggml_cpy(ctx0,
|
1468 |
KQV_merged,
|
1469 |
ggml_new_tensor_2d(ctx0, GGML_TYPE_F32, n_embd, N));
|
|
|
1470 |
ggml_set_name(cur, "KQV_merged_contiguous");
|
1471 |
|
1472 |
// projection (no bias)
|
@@ -1478,7 +1584,6 @@ static bool llama_eval_internal(
|
|
1478 |
}
|
1479 |
|
1480 |
lctx.use_buf(ctx0, 1);
|
1481 |
-
//ggml_cuda_set_scratch(1);
|
1482 |
|
1483 |
struct ggml_tensor * inpFF = ggml_add(ctx0, cur, inpSA);
|
1484 |
offload_func(inpFF);
|
@@ -1536,32 +1641,24 @@ static bool llama_eval_internal(
|
|
1536 |
}
|
1537 |
|
1538 |
lctx.use_buf(ctx0, 0);
|
1539 |
-
//ggml_cuda_set_scratch(0);
|
1540 |
|
1541 |
// used at the end to optionally extract the embeddings
|
1542 |
struct ggml_tensor * embeddings = NULL;
|
1543 |
|
1544 |
-
offload_func_t offload_func = llama_nop;
|
1545 |
-
|
1546 |
-
#ifdef GGML_USE_CUBLAS
|
1547 |
-
if (n_gpu_layers > n_layer) {
|
1548 |
-
offload_func = ggml_cuda_assign_buffers; // sets the output backend to GPU
|
1549 |
-
}
|
1550 |
-
#endif // GGML_USE_CUBLAS
|
1551 |
|
1552 |
// norm
|
1553 |
{
|
1554 |
cur = ggml_rms_norm(ctx0, inpL);
|
1555 |
-
|
1556 |
ggml_set_name(cur, "rms_norm_inpL");
|
1557 |
|
1558 |
cur = ggml_rms_norm(ctx0, cur);
|
1559 |
-
|
1560 |
ggml_set_name(cur, "rms_norm_after");
|
1561 |
|
1562 |
// cur = cur*norm(broadcasted)
|
1563 |
cur = ggml_mul(ctx0, cur, model.norm);
|
1564 |
-
|
1565 |
ggml_set_name(cur, "result_norm");
|
1566 |
|
1567 |
embeddings = cur;
|
@@ -2552,8 +2649,8 @@ struct llama_context * llama_init_from_file(
|
|
2552 |
|
2553 |
ggml_type memory_type = params.f16_kv ? GGML_TYPE_F16 : GGML_TYPE_F32;
|
2554 |
|
2555 |
-
if (!llama_model_load(path_model, *ctx, params.n_ctx, params.n_batch, params.n_gpu_layers,
|
2556 |
-
params.
|
2557 |
params.vocab_only, params.progress_callback, params.progress_callback_user_data)) {
|
2558 |
fprintf(stderr, "%s: failed to load model\n", __func__);
|
2559 |
llama_free(ctx);
|
@@ -2562,7 +2659,7 @@ struct llama_context * llama_init_from_file(
|
|
2562 |
|
2563 |
// reserve memory for context buffers
|
2564 |
if (!params.vocab_only) {
|
2565 |
-
if (!kv_cache_init(ctx->model.hparams, ctx->model.kv_self, memory_type, ctx->model.hparams.n_ctx)) {
|
2566 |
fprintf(stderr, "%s: kv_cache_init() failed for self-attention cache\n", __func__);
|
2567 |
llama_free(ctx);
|
2568 |
return nullptr;
|
|
|
40 |
#include <sstream>
|
41 |
#include <numeric>
|
42 |
|
43 |
+
#if defined(_MSC_VER)
|
44 |
+
#pragma warning(disable: 4244 4267) // possible loss of data
|
45 |
+
#endif
|
46 |
+
|
47 |
#define LLAMA_USE_SCRATCH
|
48 |
#define LLAMA_MAX_SCRATCH_BUFFERS 16
|
49 |
|
|
|
169 |
if (ctx) {
|
170 |
ggml_free(ctx);
|
171 |
}
|
172 |
+
|
173 |
+
#ifdef GGML_USE_CUBLAS
|
174 |
+
ggml_cuda_free_data(k);
|
175 |
+
ggml_cuda_free_data(v);
|
176 |
+
#endif // GGML_USE_CUBLAS
|
177 |
}
|
178 |
};
|
179 |
|
|
|
219 |
for (size_t i = 0; i < tensors_by_name.size(); ++i) {
|
220 |
ggml_cuda_free_data(tensors_by_name[i].second);
|
221 |
}
|
222 |
+
ggml_cuda_free_scratch();
|
223 |
#elif defined(GGML_USE_CLBLAST)
|
224 |
for (size_t i = 0; i < tensors_by_name.size(); ++i) {
|
225 |
ggml_cl_free_data(tensors_by_name[i].second);
|
|
|
877 |
const struct llama_hparams & hparams,
|
878 |
struct llama_kv_cache & cache,
|
879 |
ggml_type wtype,
|
880 |
+
int n_ctx,
|
881 |
+
int n_gpu_layers) {
|
882 |
const int n_embd = hparams.n_embd;
|
883 |
const int n_layer = hparams.n_layer;
|
884 |
|
|
|
904 |
ggml_set_name(cache.k, "cache_k");
|
905 |
ggml_set_name(cache.v, "cache_v");
|
906 |
|
907 |
+
#ifdef GGML_USE_CUBLAS
|
908 |
+
if (n_gpu_layers > n_layer + 1) {
|
909 |
+
ggml_cuda_assign_buffers_no_scratch(cache.v);
|
910 |
+
}
|
911 |
+
if (n_gpu_layers > n_layer + 2) {
|
912 |
+
ggml_cuda_assign_buffers_no_scratch(cache.k);
|
913 |
+
}
|
914 |
+
#endif // GGML_USE_CUBLAS
|
915 |
+
|
916 |
return true;
|
917 |
}
|
918 |
|
|
|
923 |
/*.gpu_layers =*/ 0,
|
924 |
/*.main_gpu =*/ 0,
|
925 |
/*.tensor_split =*/ {0},
|
926 |
+
/*.low_vram =*/ false,
|
927 |
/*.seed =*/ -1,
|
928 |
/*.f16_kv =*/ true,
|
929 |
/*.logits_all =*/ false,
|
|
|
1032 |
int n_gpu_layers,
|
1033 |
int main_gpu,
|
1034 |
const float * tensor_split,
|
1035 |
+
bool low_vram,
|
1036 |
ggml_type memory_type,
|
1037 |
bool use_mmap,
|
1038 |
bool use_mlock,
|
|
|
1159 |
ml->ggml_ctx = ctx;
|
1160 |
|
1161 |
model.tok_embeddings = ml->get_tensor("tok_embeddings.weight", {n_embd, n_vocab}, GGML_BACKEND_CPU);
|
|
|
1162 |
|
1163 |
// "output" tensor
|
1164 |
{
|
1165 |
+
ggml_backend backend_norm;
|
1166 |
ggml_backend backend_output;
|
1167 |
if (n_gpu_layers > int(n_layer)) { // NOLINT
|
1168 |
+
// norm is not performance relevant on its own but keeping it in VRAM reduces data copying
|
1169 |
+
// on Windows however this is detrimental unless everything is on the GPU
|
1170 |
+
#ifndef _WIN32
|
1171 |
+
backend_norm = low_vram ? GGML_BACKEND_CPU : LLAMA_BACKEND_OFFLOAD;
|
1172 |
+
#else
|
1173 |
+
backend_norm = low_vram || n_gpu_layers <= (int) n_layer + 2 ? GGML_BACKEND_CPU : LLAMA_BACKEND_OFFLOAD;
|
1174 |
+
#endif // _WIN32
|
1175 |
+
|
1176 |
backend_output = LLAMA_BACKEND_OFFLOAD_SPLIT;
|
1177 |
} else {
|
1178 |
+
backend_norm = GGML_BACKEND_CPU;
|
1179 |
backend_output = GGML_BACKEND_CPU;
|
1180 |
}
|
1181 |
|
1182 |
+
model.norm = ml->get_tensor("norm.weight", {n_embd}, backend_norm);
|
1183 |
model.output = ml->get_tensor("output.weight", {n_embd, n_vocab}, backend_output);
|
1184 |
+
if (backend_norm == GGML_BACKEND_GPU) {
|
1185 |
+
vram_weights += ggml_nbytes(model.norm);
|
1186 |
+
}
|
1187 |
+
if (backend_output == GGML_BACKEND_GPU_SPLIT) {
|
1188 |
+
vram_weights += ggml_nbytes(model.output);
|
1189 |
+
}
|
1190 |
}
|
1191 |
|
1192 |
const int i_gpu_start = n_layer - n_gpu_layers;
|
|
|
1246 |
(void) vram_scratch;
|
1247 |
(void) n_batch;
|
1248 |
#ifdef GGML_USE_CUBLAS
|
1249 |
+
if (low_vram) {
|
1250 |
+
fprintf(stderr, "%s: not allocating a VRAM scratch buffer due to low VRAM option\n", __func__);
|
1251 |
+
ggml_cuda_set_scratch_size(0); // disable scratch
|
1252 |
+
} else {
|
1253 |
+
vram_scratch = n_batch * MB;
|
1254 |
+
ggml_cuda_set_scratch_size(vram_scratch);
|
1255 |
+
if (n_gpu_layers > 0) {
|
1256 |
+
fprintf(stderr, "%s: allocating batch_size x 1 MB = %ld MB VRAM for the scratch buffer\n",
|
1257 |
+
__func__, vram_scratch / MB);
|
1258 |
+
}
|
1259 |
}
|
1260 |
#endif // GGML_USE_CUBLAS
|
1261 |
#if defined(GGML_USE_CUBLAS) || defined(GGML_USE_CLBLAST)
|
1262 |
const int n_gpu = std::min(n_gpu_layers, int(hparams.n_layer));
|
1263 |
|
1264 |
+
fprintf(stderr, "%s: offloading %d repeating layers to GPU\n", __func__, n_gpu);
|
1265 |
if (n_gpu_layers > (int) hparams.n_layer) {
|
1266 |
+
fprintf(stderr, "%s: offloading non-repeating layers to GPU\n", __func__);
|
1267 |
+
}
|
1268 |
+
size_t vram_kv_cache = 0;
|
1269 |
+
if (n_gpu_layers > (int) hparams.n_layer + 1) {
|
1270 |
+
if (low_vram) {
|
1271 |
+
fprintf(stderr, "%s: cannot offload v cache to GPU due to low VRAM option\n", __func__);
|
1272 |
+
} else {
|
1273 |
+
fprintf(stderr, "%s: offloading v cache to GPU\n", __func__);
|
1274 |
+
vram_kv_cache += MEM_REQ_KV_SELF().at(model.type) / 2;
|
1275 |
+
}
|
1276 |
+
}
|
1277 |
+
if (n_gpu_layers > (int) hparams.n_layer + 2) {
|
1278 |
+
if (low_vram) {
|
1279 |
+
fprintf(stderr, "%s: cannot offload k cache to GPU due to low VRAM option\n", __func__);
|
1280 |
+
} else {
|
1281 |
+
fprintf(stderr, "%s: offloading k cache to GPU\n", __func__);
|
1282 |
+
vram_kv_cache += MEM_REQ_KV_SELF().at(model.type) / 2;
|
1283 |
+
}
|
1284 |
}
|
1285 |
+
const int max_offloadable_layers = low_vram ? hparams.n_layer + 1 : hparams.n_layer + 3;
|
1286 |
+
fprintf(stderr, "%s: offloaded %d/%d layers to GPU\n",
|
1287 |
+
__func__, std::min(n_gpu_layers, max_offloadable_layers), hparams.n_layer + 3);
|
1288 |
fprintf(stderr, "%s: total VRAM used: %zu MB\n",
|
1289 |
+
__func__, (vram_weights + vram_scratch + vram_kv_cache + MB - 1) / MB); // round up
|
1290 |
#else
|
1291 |
(void) n_gpu_layers;
|
1292 |
#endif
|
|
|
1325 |
int n_gpu_layers,
|
1326 |
int main_gpu,
|
1327 |
float * tensor_split,
|
1328 |
+
bool low_vram,
|
1329 |
ggml_type memory_type,
|
1330 |
bool use_mmap,
|
1331 |
bool use_mlock,
|
|
|
1333 |
llama_progress_callback progress_callback,
|
1334 |
void *progress_callback_user_data) {
|
1335 |
try {
|
1336 |
+
llama_model_load_internal(fname, lctx, n_ctx, n_batch, n_gpu_layers, main_gpu, tensor_split, low_vram, memory_type,
|
1337 |
use_mmap, use_mlock, vocab_only, progress_callback, progress_callback_user_data);
|
1338 |
return true;
|
1339 |
} catch (const std::exception & err) {
|
|
|
1409 |
const int i_gpu_start = n_layer - n_gpu_layers;
|
1410 |
(void) i_gpu_start;
|
1411 |
|
1412 |
+
// offload functions set the tensor output backend to GPU
|
1413 |
+
// tensors are GPU-accelerated if any input or the output has been offloaded
|
1414 |
+
//
|
1415 |
+
// with the low VRAM option VRAM scratch is disabled in llama_load_model_internal
|
1416 |
+
// in that case ggml_cuda_assign_buffers has no effect
|
1417 |
+
offload_func_t offload_func_nr = llama_nop; // nr = non-repeating
|
1418 |
+
offload_func_t offload_func_kq = llama_nop;
|
1419 |
+
offload_func_t offload_func_v = llama_nop;
|
1420 |
+
|
1421 |
+
#ifdef GGML_USE_CUBLAS
|
1422 |
+
if (n_gpu_layers > n_layer) {
|
1423 |
+
offload_func_nr = ggml_cuda_assign_buffers;
|
1424 |
+
}
|
1425 |
+
if (n_gpu_layers > n_layer + 1) {
|
1426 |
+
offload_func_v = ggml_cuda_assign_buffers;
|
1427 |
+
}
|
1428 |
+
if (n_gpu_layers > n_layer + 2) {
|
1429 |
+
offload_func_kq = ggml_cuda_assign_buffers;
|
1430 |
+
}
|
1431 |
+
#endif // GGML_USE_CUBLAS
|
1432 |
+
|
1433 |
for (int il = 0; il < n_layer; ++il) {
|
1434 |
offload_func_t offload_func = llama_nop;
|
1435 |
|
1436 |
#ifdef GGML_USE_CUBLAS
|
1437 |
if (il >= i_gpu_start) {
|
1438 |
+
offload_func = ggml_cuda_assign_buffers;
|
1439 |
}
|
1440 |
#endif // GGML_USE_CUBLAS
|
1441 |
|
|
|
1458 |
// self-attention
|
1459 |
{
|
1460 |
// compute Q and K and RoPE them
|
|
|
|
|
|
|
|
|
1461 |
struct ggml_tensor * tmpk = ggml_mul_mat(ctx0, model.layers[il].wk, cur);
|
1462 |
+
offload_func_kq(tmpk);
|
1463 |
ggml_set_name(tmpk, "tmpk");
|
1464 |
|
1465 |
+
struct ggml_tensor * tmpq = ggml_mul_mat(ctx0, model.layers[il].wq, cur);
|
1466 |
+
offload_func_kq(tmpq);
|
1467 |
+
ggml_set_name(tmpq, "tmpq");
|
1468 |
+
|
1469 |
struct ggml_tensor * Kcur = ggml_rope_inplace(ctx0, ggml_reshape_3d(ctx0, tmpk, n_embd/n_head, n_head, N), n_past, n_rot, 0);
|
1470 |
+
offload_func_kq(Kcur);
|
1471 |
ggml_set_name(Kcur, "Kcur");
|
1472 |
|
1473 |
struct ggml_tensor * Qcur = ggml_rope_inplace(ctx0, ggml_reshape_3d(ctx0, tmpq, n_embd/n_head, n_head, N), n_past, n_rot, 0);
|
1474 |
+
offload_func_kq(Qcur);
|
1475 |
ggml_set_name(Qcur, "Qcur");
|
1476 |
|
1477 |
// store key and value to memory
|
1478 |
{
|
1479 |
// compute the transposed [N, n_embd] V matrix
|
1480 |
+
|
1481 |
+
struct ggml_tensor * tmpv = ggml_mul_mat(ctx0, model.layers[il].wv, cur);
|
1482 |
+
offload_func_v(tmpv);
|
1483 |
+
ggml_set_name(tmpv, "tmpv");
|
1484 |
+
|
1485 |
+
struct ggml_tensor * Vcur = ggml_transpose(ctx0, ggml_reshape_2d(ctx0, tmpv, n_embd, N));
|
1486 |
+
offload_func_v(Vcur);
|
1487 |
ggml_set_name(Vcur, "Vcur");
|
1488 |
|
1489 |
struct ggml_tensor * k = ggml_view_1d(ctx0, kv_self.k, N*n_embd, (ggml_element_size(kv_self.k)*n_embd)*(il*n_ctx + n_past));
|
1490 |
+
offload_func_kq(k);
|
1491 |
ggml_set_name(k, "k");
|
1492 |
+
|
1493 |
struct ggml_tensor * v = ggml_view_2d(ctx0, kv_self.v, N, n_embd,
|
1494 |
( n_ctx)*ggml_element_size(kv_self.v),
|
1495 |
(il*n_ctx)*ggml_element_size(kv_self.v)*n_embd + n_past*ggml_element_size(kv_self.v));
|
1496 |
+
offload_func_v(v);
|
1497 |
ggml_set_name(v, "v");
|
1498 |
|
1499 |
// important: storing RoPE-ed version of K in the KV cache!
|
|
|
1505 |
ggml_permute(ctx0,
|
1506 |
Qcur,
|
1507 |
0, 2, 1, 3);
|
1508 |
+
offload_func_kq(Q);
|
1509 |
ggml_set_name(Q, "Q");
|
1510 |
|
1511 |
struct ggml_tensor * K =
|
|
|
1514 |
ggml_view_1d(ctx0, kv_self.k, (n_past + N)*n_embd, il*n_ctx*ggml_element_size(kv_self.k)*n_embd),
|
1515 |
n_embd/n_head, n_head, n_past + N),
|
1516 |
0, 2, 1, 3);
|
1517 |
+
offload_func_kq(K);
|
1518 |
ggml_set_name(K, "K");
|
1519 |
|
1520 |
// K * Q
|
1521 |
struct ggml_tensor * KQ = ggml_mul_mat(ctx0, K, Q);
|
1522 |
+
offload_func_kq(KQ);
|
1523 |
ggml_set_name(KQ, "KQ");
|
1524 |
|
1525 |
// KQ_scaled = KQ / sqrt(n_embd/n_head)
|
|
|
1528 |
|
1529 |
// KQ_scaled shape [n_past + N, N, n_head, 1]
|
1530 |
struct ggml_tensor * KQ_scaled = ggml_scale_inplace(ctx0, KQ, KQ_scale);
|
1531 |
+
offload_func_kq(KQ_scaled);
|
1532 |
ggml_set_name(KQ_scaled, "KQ_scaled");
|
1533 |
|
1534 |
// KQ_masked = mask_past(KQ_scaled)
|
1535 |
struct ggml_tensor * KQ_masked = ggml_diag_mask_inf_inplace(ctx0, KQ_scaled, n_past);
|
1536 |
+
offload_func_kq(KQ_masked);
|
1537 |
ggml_set_name(KQ_masked, "KQ_masked");
|
1538 |
|
1539 |
// KQ = soft_max(KQ_masked)
|
1540 |
struct ggml_tensor * KQ_soft_max = ggml_soft_max_inplace(ctx0, KQ_masked);
|
1541 |
+
offload_func_v(KQ_soft_max);
|
1542 |
ggml_set_name(KQ_soft_max, "KQ_soft_max");
|
1543 |
|
1544 |
// split cached V into n_head heads
|
|
|
1548 |
n_ctx*ggml_element_size(kv_self.v),
|
1549 |
n_ctx*ggml_element_size(kv_self.v)*n_embd/n_head,
|
1550 |
il*n_ctx*ggml_element_size(kv_self.v)*n_embd);
|
1551 |
+
offload_func_v(V);
|
1552 |
ggml_set_name(V, "V");
|
1553 |
|
1554 |
#if 1
|
1555 |
struct ggml_tensor * KQV = ggml_mul_mat(ctx0, V, KQ_soft_max);
|
1556 |
+
offload_func_v(KQV);
|
1557 |
ggml_set_name(KQV, "KQV");
|
1558 |
#else
|
1559 |
// make V contiguous in memory to speed up the matmul, however we waste time on the copy
|
|
|
1565 |
|
1566 |
// KQV_merged = KQV.permute(0, 2, 1, 3)
|
1567 |
struct ggml_tensor * KQV_merged = ggml_permute(ctx0, KQV, 0, 2, 1, 3);
|
1568 |
+
offload_func_v(KQV_merged);
|
1569 |
ggml_set_name(KQV_merged, "KQV_merged");
|
1570 |
|
1571 |
// cur = KQV_merged.contiguous().view(n_embd, N)
|
1572 |
cur = ggml_cpy(ctx0,
|
1573 |
KQV_merged,
|
1574 |
ggml_new_tensor_2d(ctx0, GGML_TYPE_F32, n_embd, N));
|
1575 |
+
offload_func_v(cur);
|
1576 |
ggml_set_name(cur, "KQV_merged_contiguous");
|
1577 |
|
1578 |
// projection (no bias)
|
|
|
1584 |
}
|
1585 |
|
1586 |
lctx.use_buf(ctx0, 1);
|
|
|
1587 |
|
1588 |
struct ggml_tensor * inpFF = ggml_add(ctx0, cur, inpSA);
|
1589 |
offload_func(inpFF);
|
|
|
1641 |
}
|
1642 |
|
1643 |
lctx.use_buf(ctx0, 0);
|
|
|
1644 |
|
1645 |
// used at the end to optionally extract the embeddings
|
1646 |
struct ggml_tensor * embeddings = NULL;
|
1647 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1648 |
|
1649 |
// norm
|
1650 |
{
|
1651 |
cur = ggml_rms_norm(ctx0, inpL);
|
1652 |
+
offload_func_nr(cur);
|
1653 |
ggml_set_name(cur, "rms_norm_inpL");
|
1654 |
|
1655 |
cur = ggml_rms_norm(ctx0, cur);
|
1656 |
+
offload_func_nr(cur);
|
1657 |
ggml_set_name(cur, "rms_norm_after");
|
1658 |
|
1659 |
// cur = cur*norm(broadcasted)
|
1660 |
cur = ggml_mul(ctx0, cur, model.norm);
|
1661 |
+
// offload_func_nr(cur); // TODO CPU + GPU mirrored backend
|
1662 |
ggml_set_name(cur, "result_norm");
|
1663 |
|
1664 |
embeddings = cur;
|
|
|
2649 |
|
2650 |
ggml_type memory_type = params.f16_kv ? GGML_TYPE_F16 : GGML_TYPE_F32;
|
2651 |
|
2652 |
+
if (!llama_model_load(path_model, *ctx, params.n_ctx, params.n_batch, params.n_gpu_layers, params.main_gpu,
|
2653 |
+
params.tensor_split, params.low_vram, memory_type, params.use_mmap, params.use_mlock,
|
2654 |
params.vocab_only, params.progress_callback, params.progress_callback_user_data)) {
|
2655 |
fprintf(stderr, "%s: failed to load model\n", __func__);
|
2656 |
llama_free(ctx);
|
|
|
2659 |
|
2660 |
// reserve memory for context buffers
|
2661 |
if (!params.vocab_only) {
|
2662 |
+
if (!kv_cache_init(ctx->model.hparams, ctx->model.kv_self, memory_type, ctx->model.hparams.n_ctx, params.n_gpu_layers)) {
|
2663 |
fprintf(stderr, "%s: kv_cache_init() failed for self-attention cache\n", __func__);
|
2664 |
llama_free(ctx);
|
2665 |
return nullptr;
|
llama.h
CHANGED
@@ -77,6 +77,7 @@ extern "C" {
|
|
77 |
int n_gpu_layers; // number of layers to store in VRAM
|
78 |
int main_gpu; // the GPU that is used for scratch and small tensors
|
79 |
float tensor_split[LLAMA_MAX_DEVICES]; // how to split layers across multiple GPUs
|
|
|
80 |
int seed; // RNG seed, -1 for random
|
81 |
|
82 |
bool f16_kv; // use fp16 for KV cache
|
@@ -243,9 +244,9 @@ extern "C" {
|
|
243 |
LLAMA_API const char * llama_token_to_str(const struct llama_context * ctx, llama_token token);
|
244 |
|
245 |
// Special tokens
|
246 |
-
LLAMA_API llama_token llama_token_bos();
|
247 |
-
LLAMA_API llama_token llama_token_eos();
|
248 |
-
LLAMA_API llama_token llama_token_nl();
|
249 |
|
250 |
// Sampling functions
|
251 |
|
|
|
77 |
int n_gpu_layers; // number of layers to store in VRAM
|
78 |
int main_gpu; // the GPU that is used for scratch and small tensors
|
79 |
float tensor_split[LLAMA_MAX_DEVICES]; // how to split layers across multiple GPUs
|
80 |
+
bool low_vram; // if true, reduce VRAM usage at the cost of performance
|
81 |
int seed; // RNG seed, -1 for random
|
82 |
|
83 |
bool f16_kv; // use fp16 for KV cache
|
|
|
244 |
LLAMA_API const char * llama_token_to_str(const struct llama_context * ctx, llama_token token);
|
245 |
|
246 |
// Special tokens
|
247 |
+
LLAMA_API llama_token llama_token_bos(); // beginning-of-sentence
|
248 |
+
LLAMA_API llama_token llama_token_eos(); // end-of-sentence
|
249 |
+
LLAMA_API llama_token llama_token_nl(); // next-line
|
250 |
|
251 |
// Sampling functions
|
252 |
|
spm-headers/ggml.h
ADDED
@@ -0,0 +1,1319 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#pragma once
|
2 |
+
|
3 |
+
//
|
4 |
+
// GGML Tensor Library
|
5 |
+
//
|
6 |
+
// This documentation is still a work in progress.
|
7 |
+
// If you wish some specific topics to be covered, feel free to drop a comment:
|
8 |
+
//
|
9 |
+
// https://github.com/ggerganov/whisper.cpp/issues/40
|
10 |
+
//
|
11 |
+
// ## Overview
|
12 |
+
//
|
13 |
+
// This library implements:
|
14 |
+
//
|
15 |
+
// - a set of tensor operations
|
16 |
+
// - automatic differentiation
|
17 |
+
// - basic optimization algorithms
|
18 |
+
//
|
19 |
+
// The aim of this library is to provide a minimalistic approach for various machine learning tasks. This includes,
|
20 |
+
// but is not limited to, the following:
|
21 |
+
//
|
22 |
+
// - linear regression
|
23 |
+
// - support vector machines
|
24 |
+
// - neural networks
|
25 |
+
//
|
26 |
+
// The library allows the user to define a certain function using the available tensor operations. This function
|
27 |
+
// definition is represented internally via a computation graph. Each tensor operation in the function definition
|
28 |
+
// corresponds to a node in the graph. Having the computation graph defined, the user can choose to compute the
|
29 |
+
// function's value and/or its gradient with respect to the input variables. Optionally, the function can be optimized
|
30 |
+
// using one of the available optimization algorithms.
|
31 |
+
//
|
32 |
+
// For example, here we define the function: f(x) = a*x^2 + b
|
33 |
+
//
|
34 |
+
// {
|
35 |
+
// struct ggml_init_params params = {
|
36 |
+
// .mem_size = 16*1024*1024,
|
37 |
+
// .mem_buffer = NULL,
|
38 |
+
// };
|
39 |
+
//
|
40 |
+
// // memory allocation happens here
|
41 |
+
// struct ggml_context * ctx = ggml_init(params);
|
42 |
+
//
|
43 |
+
// struct ggml_tensor * x = ggml_new_tensor_1d(ctx, GGML_TYPE_F32, 1);
|
44 |
+
//
|
45 |
+
// ggml_set_param(ctx, x); // x is an input variable
|
46 |
+
//
|
47 |
+
// struct ggml_tensor * a = ggml_new_tensor_1d(ctx, GGML_TYPE_F32, 1);
|
48 |
+
// struct ggml_tensor * b = ggml_new_tensor_1d(ctx, GGML_TYPE_F32, 1);
|
49 |
+
// struct ggml_tensor * x2 = ggml_mul(ctx, x, x);
|
50 |
+
// struct ggml_tensor * f = ggml_add(ctx, ggml_mul(ctx, a, x2), b);
|
51 |
+
//
|
52 |
+
// ...
|
53 |
+
// }
|
54 |
+
//
|
55 |
+
// Notice that the function definition above does not involve any actual computation. The computation is performed only
|
56 |
+
// when the user explicitly requests it. For example, to compute the function's value at x = 2.0:
|
57 |
+
//
|
58 |
+
// {
|
59 |
+
// ...
|
60 |
+
//
|
61 |
+
// struct ggml_cgraph gf = ggml_build_forward(f);
|
62 |
+
//
|
63 |
+
// // set the input variable and parameter values
|
64 |
+
// ggml_set_f32(x, 2.0f);
|
65 |
+
// ggml_set_f32(a, 3.0f);
|
66 |
+
// ggml_set_f32(b, 4.0f);
|
67 |
+
//
|
68 |
+
// ggml_graph_compute(ctx0, &gf);
|
69 |
+
//
|
70 |
+
// printf("f = %f\n", ggml_get_f32_1d(f, 0));
|
71 |
+
//
|
72 |
+
// ...
|
73 |
+
// }
|
74 |
+
//
|
75 |
+
// The actual computation is performed in the ggml_graph_compute() function.
|
76 |
+
//
|
77 |
+
// The ggml_new_tensor_...() functions create new tensors. They are allocated in the memory buffer provided to the
|
78 |
+
// ggml_init() function. You have to be careful not to exceed the memory buffer size. Therefore, you have to know
|
79 |
+
// in advance how much memory you need for your computation. Alternatively, you can allocate a large enough memory
|
80 |
+
// and after defining the computation graph, call the ggml_used_mem() function to find out how much memory was
|
81 |
+
// actually needed.
|
82 |
+
//
|
83 |
+
// The ggml_set_param() function marks a tensor as an input variable. This is used by the automatic
|
84 |
+
// differentiation and optimization algorithms.
|
85 |
+
//
|
86 |
+
// The described approach allows to define the function graph once and then compute its forward or backward graphs
|
87 |
+
// multiple times. All computations will use the same memory buffer allocated in the ggml_init() function. This way
|
88 |
+
// the user can avoid the memory allocation overhead at runtime.
|
89 |
+
//
|
90 |
+
// The library supports multi-dimensional tensors - up to 4 dimensions. The FP16 and FP32 data types are first class
|
91 |
+
// citizens, but in theory the library can be extended to support FP8 and integer data types.
|
92 |
+
//
|
93 |
+
// Each tensor operation produces a new tensor. Initially the library was envisioned to support only the use of unary
|
94 |
+
// and binary operations. Most of the available operations fall into one of these two categories. With time, it became
|
95 |
+
// clear that the library needs to support more complex operations. The way to support these operations is not clear
|
96 |
+
// yet, but a few examples are demonstrated in the following operations:
|
97 |
+
//
|
98 |
+
// - ggml_permute()
|
99 |
+
// - ggml_conv_1d_1s()
|
100 |
+
// - ggml_conv_1d_2s()
|
101 |
+
//
|
102 |
+
// For each tensor operator, the library implements a forward and backward computation function. The forward function
|
103 |
+
// computes the output tensor value given the input tensor values. The backward function computes the adjoint of the
|
104 |
+
// input tensors given the adjoint of the output tensor. For a detailed explanation of what this means, take a
|
105 |
+
// calculus class, or watch the following video:
|
106 |
+
//
|
107 |
+
// What is Automatic Differentiation?
|
108 |
+
// https://www.youtube.com/watch?v=wG_nF1awSSY
|
109 |
+
//
|
110 |
+
//
|
111 |
+
// ## Tensor data (struct ggml_tensor)
|
112 |
+
//
|
113 |
+
// The tensors are stored in memory via the ggml_tensor struct. The structure provides information about the size of
|
114 |
+
// the tensor, the data type, and the memory buffer where the tensor data is stored. Additionally, it contains
|
115 |
+
// pointers to the "source" tensors - i.e. the tensors that were used to compute the current tensor. For example:
|
116 |
+
//
|
117 |
+
// {
|
118 |
+
// struct ggml_tensor * c = ggml_add(ctx, a, b);
|
119 |
+
//
|
120 |
+
// assert(c->src[0] == a);
|
121 |
+
// assert(c->src[1] == b);
|
122 |
+
// }
|
123 |
+
//
|
124 |
+
// The multi-dimensional tensors are stored in row-major order. The ggml_tensor struct contains fields for the
|
125 |
+
// number of elements in each dimension ("ne") as well as the number of bytes ("nb", a.k.a. stride). This allows
|
126 |
+
// to store tensors that are not contiguous in memory, which is useful for operations such as transposition and
|
127 |
+
// permutation. All tensor operations have to take the stride into account and not assume that the tensor is
|
128 |
+
// contiguous in memory.
|
129 |
+
//
|
130 |
+
// The data of the tensor is accessed via the "data" pointer. For example:
|
131 |
+
//
|
132 |
+
// {
|
133 |
+
// struct ggml_tensor * a = ggml_new_tensor_2d(ctx, GGML_TYPE_F32, 2, 3);
|
134 |
+
//
|
135 |
+
// // a[1, 2] = 1.0f;
|
136 |
+
// *(float *) ((char *) a->data + 2*a->nb[1] + 1*a->nb[0]) = 1.0f;
|
137 |
+
//
|
138 |
+
// // a[2, 0] = 2.0f;
|
139 |
+
// *(float *) ((char *) a->data + 0*a->nb[1] + 2*a->nb[0]) = 2.0f;
|
140 |
+
//
|
141 |
+
// ...
|
142 |
+
// }
|
143 |
+
//
|
144 |
+
// Alternatively, there are helper functions, such as ggml_get_f32_1d() and ggml_set_f32_1d() that can be used.
|
145 |
+
//
|
146 |
+
// ## The matrix multiplication operator (ggml_mul_mat)
|
147 |
+
//
|
148 |
+
// TODO
|
149 |
+
//
|
150 |
+
//
|
151 |
+
// ## Multi-threading
|
152 |
+
//
|
153 |
+
// TODO
|
154 |
+
//
|
155 |
+
//
|
156 |
+
// ## Overview of ggml.c
|
157 |
+
//
|
158 |
+
// TODO
|
159 |
+
//
|
160 |
+
//
|
161 |
+
// ## SIMD optimizations
|
162 |
+
//
|
163 |
+
// TODO
|
164 |
+
//
|
165 |
+
//
|
166 |
+
// ## Debugging ggml
|
167 |
+
//
|
168 |
+
// TODO
|
169 |
+
//
|
170 |
+
//
|
171 |
+
|
172 |
+
#ifdef GGML_SHARED
|
173 |
+
# if defined(_WIN32) && !defined(__MINGW32__)
|
174 |
+
# ifdef GGML_BUILD
|
175 |
+
# define GGML_API __declspec(dllexport)
|
176 |
+
# else
|
177 |
+
# define GGML_API __declspec(dllimport)
|
178 |
+
# endif
|
179 |
+
# else
|
180 |
+
# define GGML_API __attribute__ ((visibility ("default")))
|
181 |
+
# endif
|
182 |
+
#else
|
183 |
+
# define GGML_API
|
184 |
+
#endif
|
185 |
+
|
186 |
+
#include <stdint.h>
|
187 |
+
#include <stddef.h>
|
188 |
+
#include <stdbool.h>
|
189 |
+
|
190 |
+
#define GGML_FILE_MAGIC 0x67676d6c // "ggml"
|
191 |
+
#define GGML_FILE_VERSION 1
|
192 |
+
|
193 |
+
#define GGML_QNT_VERSION 2 // bump this on quantization format changes
|
194 |
+
#define GGML_QNT_VERSION_FACTOR 1000 // do not change this
|
195 |
+
|
196 |
+
#define GGML_MAX_DIMS 4
|
197 |
+
#define GGML_MAX_NODES 4096
|
198 |
+
#define GGML_MAX_PARAMS 256
|
199 |
+
#define GGML_MAX_CONTEXTS 64
|
200 |
+
#define GGML_MAX_OPT 4
|
201 |
+
#define GGML_MAX_NAME 32
|
202 |
+
#define GGML_DEFAULT_N_THREADS 4
|
203 |
+
|
204 |
+
#define GGML_ASSERT(x) \
|
205 |
+
do { \
|
206 |
+
if (!(x)) { \
|
207 |
+
fprintf(stderr, "GGML_ASSERT: %s:%d: %s\n", __FILE__, __LINE__, #x); \
|
208 |
+
abort(); \
|
209 |
+
} \
|
210 |
+
} while (0)
|
211 |
+
|
212 |
+
#ifdef __cplusplus
|
213 |
+
extern "C" {
|
214 |
+
#endif
|
215 |
+
|
216 |
+
#ifdef __ARM_NEON
|
217 |
+
// we use the built-in 16-bit float type
|
218 |
+
typedef __fp16 ggml_fp16_t;
|
219 |
+
#else
|
220 |
+
typedef uint16_t ggml_fp16_t;
|
221 |
+
#endif
|
222 |
+
|
223 |
+
// convert FP16 <-> FP32
|
224 |
+
GGML_API float ggml_fp16_to_fp32(ggml_fp16_t x);
|
225 |
+
GGML_API ggml_fp16_t ggml_fp32_to_fp16(float x);
|
226 |
+
|
227 |
+
GGML_API void ggml_fp16_to_fp32_row(const ggml_fp16_t * x, float * y, size_t n);
|
228 |
+
GGML_API void ggml_fp32_to_fp16_row(const float * x, ggml_fp16_t * y, size_t n);
|
229 |
+
|
230 |
+
struct ggml_object;
|
231 |
+
struct ggml_context;
|
232 |
+
|
233 |
+
enum ggml_type {
|
234 |
+
GGML_TYPE_F32 = 0,
|
235 |
+
GGML_TYPE_F16 = 1,
|
236 |
+
GGML_TYPE_Q4_0 = 2,
|
237 |
+
GGML_TYPE_Q4_1 = 3,
|
238 |
+
// GGML_TYPE_Q4_2 = 4, support has been removed
|
239 |
+
// GGML_TYPE_Q4_3 (5) support has been removed
|
240 |
+
GGML_TYPE_Q5_0 = 6,
|
241 |
+
GGML_TYPE_Q5_1 = 7,
|
242 |
+
GGML_TYPE_Q8_0 = 8,
|
243 |
+
GGML_TYPE_Q8_1 = 9,
|
244 |
+
// k-quantizations
|
245 |
+
GGML_TYPE_Q2_K = 10,
|
246 |
+
GGML_TYPE_Q3_K = 11,
|
247 |
+
GGML_TYPE_Q4_K = 12,
|
248 |
+
GGML_TYPE_Q5_K = 13,
|
249 |
+
GGML_TYPE_Q6_K = 14,
|
250 |
+
GGML_TYPE_Q8_K = 15,
|
251 |
+
GGML_TYPE_I8,
|
252 |
+
GGML_TYPE_I16,
|
253 |
+
GGML_TYPE_I32,
|
254 |
+
GGML_TYPE_COUNT,
|
255 |
+
};
|
256 |
+
|
257 |
+
enum ggml_backend {
|
258 |
+
GGML_BACKEND_CPU = 0,
|
259 |
+
GGML_BACKEND_GPU = 10,
|
260 |
+
GGML_BACKEND_GPU_SPLIT = 20,
|
261 |
+
};
|
262 |
+
|
263 |
+
// model file types
|
264 |
+
enum ggml_ftype {
|
265 |
+
GGML_FTYPE_UNKNOWN = -1,
|
266 |
+
GGML_FTYPE_ALL_F32 = 0,
|
267 |
+
GGML_FTYPE_MOSTLY_F16 = 1, // except 1d tensors
|
268 |
+
GGML_FTYPE_MOSTLY_Q4_0 = 2, // except 1d tensors
|
269 |
+
GGML_FTYPE_MOSTLY_Q4_1 = 3, // except 1d tensors
|
270 |
+
GGML_FTYPE_MOSTLY_Q4_1_SOME_F16 = 4, // tok_embeddings.weight and output.weight are F16
|
271 |
+
GGML_FTYPE_MOSTLY_Q8_0 = 7, // except 1d tensors
|
272 |
+
GGML_FTYPE_MOSTLY_Q5_0 = 8, // except 1d tensors
|
273 |
+
GGML_FTYPE_MOSTLY_Q5_1 = 9, // except 1d tensors
|
274 |
+
GGML_FTYPE_MOSTLY_Q2_K = 10, // except 1d tensors
|
275 |
+
GGML_FTYPE_MOSTLY_Q3_K = 11, // except 1d tensors
|
276 |
+
GGML_FTYPE_MOSTLY_Q4_K = 12, // except 1d tensors
|
277 |
+
GGML_FTYPE_MOSTLY_Q5_K = 13, // except 1d tensors
|
278 |
+
GGML_FTYPE_MOSTLY_Q6_K = 14, // except 1d tensors
|
279 |
+
};
|
280 |
+
|
281 |
+
// available tensor operations:
|
282 |
+
enum ggml_op {
|
283 |
+
GGML_OP_NONE = 0,
|
284 |
+
|
285 |
+
GGML_OP_DUP,
|
286 |
+
GGML_OP_ADD,
|
287 |
+
GGML_OP_ADD1,
|
288 |
+
GGML_OP_ACC,
|
289 |
+
GGML_OP_SUB,
|
290 |
+
GGML_OP_MUL,
|
291 |
+
GGML_OP_DIV,
|
292 |
+
GGML_OP_SQR,
|
293 |
+
GGML_OP_SQRT,
|
294 |
+
GGML_OP_LOG,
|
295 |
+
GGML_OP_SUM,
|
296 |
+
GGML_OP_SUM_ROWS,
|
297 |
+
GGML_OP_MEAN,
|
298 |
+
GGML_OP_REPEAT,
|
299 |
+
GGML_OP_REPEAT_BACK,
|
300 |
+
GGML_OP_ABS,
|
301 |
+
GGML_OP_SGN,
|
302 |
+
GGML_OP_NEG,
|
303 |
+
GGML_OP_STEP,
|
304 |
+
GGML_OP_RELU,
|
305 |
+
GGML_OP_GELU,
|
306 |
+
GGML_OP_SILU,
|
307 |
+
GGML_OP_SILU_BACK,
|
308 |
+
GGML_OP_NORM, // normalize
|
309 |
+
GGML_OP_RMS_NORM,
|
310 |
+
GGML_OP_RMS_NORM_BACK,
|
311 |
+
|
312 |
+
GGML_OP_MUL_MAT,
|
313 |
+
GGML_OP_OUT_PROD,
|
314 |
+
|
315 |
+
GGML_OP_SCALE,
|
316 |
+
GGML_OP_SET,
|
317 |
+
GGML_OP_CPY,
|
318 |
+
GGML_OP_CONT,
|
319 |
+
GGML_OP_RESHAPE,
|
320 |
+
GGML_OP_VIEW,
|
321 |
+
GGML_OP_PERMUTE,
|
322 |
+
GGML_OP_TRANSPOSE,
|
323 |
+
GGML_OP_GET_ROWS,
|
324 |
+
GGML_OP_GET_ROWS_BACK,
|
325 |
+
GGML_OP_DIAG,
|
326 |
+
GGML_OP_DIAG_MASK_INF,
|
327 |
+
GGML_OP_DIAG_MASK_ZERO,
|
328 |
+
GGML_OP_SOFT_MAX,
|
329 |
+
GGML_OP_SOFT_MAX_BACK,
|
330 |
+
GGML_OP_ROPE,
|
331 |
+
GGML_OP_ROPE_BACK,
|
332 |
+
GGML_OP_ALIBI,
|
333 |
+
GGML_OP_CLAMP,
|
334 |
+
GGML_OP_CONV_1D_1S,
|
335 |
+
GGML_OP_CONV_1D_2S,
|
336 |
+
|
337 |
+
GGML_OP_FLASH_ATTN,
|
338 |
+
GGML_OP_FLASH_FF,
|
339 |
+
GGML_OP_FLASH_ATTN_BACK,
|
340 |
+
|
341 |
+
GGML_OP_MAP_UNARY,
|
342 |
+
GGML_OP_MAP_BINARY,
|
343 |
+
|
344 |
+
GGML_OP_CROSS_ENTROPY_LOSS,
|
345 |
+
GGML_OP_CROSS_ENTROPY_LOSS_BACK,
|
346 |
+
|
347 |
+
GGML_OP_COUNT,
|
348 |
+
};
|
349 |
+
|
350 |
+
|
351 |
+
// ggml object
|
352 |
+
struct ggml_object {
|
353 |
+
size_t offs;
|
354 |
+
size_t size;
|
355 |
+
|
356 |
+
struct ggml_object * next;
|
357 |
+
|
358 |
+
char padding[8];
|
359 |
+
};
|
360 |
+
|
361 |
+
static const size_t GGML_OBJECT_SIZE = sizeof(struct ggml_object);
|
362 |
+
|
363 |
+
// n-dimensional tensor
|
364 |
+
struct ggml_tensor {
|
365 |
+
enum ggml_type type;
|
366 |
+
enum ggml_backend backend;
|
367 |
+
|
368 |
+
int n_dims;
|
369 |
+
int64_t ne[GGML_MAX_DIMS]; // number of elements
|
370 |
+
size_t nb[GGML_MAX_DIMS]; // stride in bytes:
|
371 |
+
// nb[0] = sizeof(type)
|
372 |
+
// nb[1] = nb[0] * ne[0] + padding
|
373 |
+
// nb[i] = nb[i-1] * ne[i-1]
|
374 |
+
|
375 |
+
// compute data
|
376 |
+
enum ggml_op op;
|
377 |
+
|
378 |
+
bool is_param;
|
379 |
+
|
380 |
+
struct ggml_tensor * grad;
|
381 |
+
struct ggml_tensor * src0;
|
382 |
+
struct ggml_tensor * src1;
|
383 |
+
struct ggml_tensor * opt[GGML_MAX_OPT];
|
384 |
+
|
385 |
+
// thread scheduling
|
386 |
+
int n_tasks;
|
387 |
+
|
388 |
+
// performance
|
389 |
+
int perf_runs;
|
390 |
+
int64_t perf_cycles;
|
391 |
+
int64_t perf_time_us;
|
392 |
+
|
393 |
+
void * data;
|
394 |
+
|
395 |
+
char name[GGML_MAX_NAME];
|
396 |
+
|
397 |
+
void * extra; // extra things e.g. for ggml-cuda.cu
|
398 |
+
|
399 |
+
char padding[4];
|
400 |
+
};
|
401 |
+
|
402 |
+
static const size_t GGML_TENSOR_SIZE = sizeof(struct ggml_tensor);
|
403 |
+
|
404 |
+
// computation graph
|
405 |
+
struct ggml_cgraph {
|
406 |
+
int n_nodes;
|
407 |
+
int n_leafs;
|
408 |
+
int n_threads;
|
409 |
+
|
410 |
+
size_t work_size;
|
411 |
+
struct ggml_tensor * work;
|
412 |
+
|
413 |
+
struct ggml_tensor * nodes[GGML_MAX_NODES];
|
414 |
+
struct ggml_tensor * grads[GGML_MAX_NODES];
|
415 |
+
struct ggml_tensor * leafs[GGML_MAX_NODES];
|
416 |
+
|
417 |
+
// performance
|
418 |
+
int perf_runs;
|
419 |
+
int64_t perf_cycles;
|
420 |
+
int64_t perf_time_us;
|
421 |
+
};
|
422 |
+
|
423 |
+
// scratch buffer
|
424 |
+
struct ggml_scratch {
|
425 |
+
size_t offs;
|
426 |
+
size_t size;
|
427 |
+
void * data;
|
428 |
+
};
|
429 |
+
|
430 |
+
struct ggml_init_params {
|
431 |
+
// memory pool
|
432 |
+
size_t mem_size; // bytes
|
433 |
+
void * mem_buffer; // if NULL, memory will be allocated internally
|
434 |
+
bool no_alloc; // don't allocate memory for the tensor data
|
435 |
+
};
|
436 |
+
|
437 |
+
|
438 |
+
// compute types
|
439 |
+
enum ggml_task_type {
|
440 |
+
GGML_TASK_INIT = 0,
|
441 |
+
GGML_TASK_COMPUTE,
|
442 |
+
GGML_TASK_FINALIZE,
|
443 |
+
};
|
444 |
+
|
445 |
+
struct ggml_compute_params {
|
446 |
+
enum ggml_task_type type;
|
447 |
+
|
448 |
+
// ith = thread index, nth = number of threads
|
449 |
+
int ith, nth;
|
450 |
+
|
451 |
+
// work buffer for all threads
|
452 |
+
size_t wsize;
|
453 |
+
void * wdata;
|
454 |
+
};
|
455 |
+
|
456 |
+
// misc
|
457 |
+
|
458 |
+
GGML_API void ggml_time_init(void); // call this once at the beginning of the program
|
459 |
+
GGML_API int64_t ggml_time_ms(void);
|
460 |
+
GGML_API int64_t ggml_time_us(void);
|
461 |
+
GGML_API int64_t ggml_cycles(void);
|
462 |
+
GGML_API int64_t ggml_cycles_per_ms(void);
|
463 |
+
|
464 |
+
GGML_API void ggml_print_object (const struct ggml_object * obj);
|
465 |
+
GGML_API void ggml_print_objects(const struct ggml_context * ctx);
|
466 |
+
|
467 |
+
GGML_API int64_t ggml_nelements (const struct ggml_tensor * tensor);
|
468 |
+
GGML_API int64_t ggml_nrows (const struct ggml_tensor * tensor);
|
469 |
+
GGML_API size_t ggml_nbytes (const struct ggml_tensor * tensor);
|
470 |
+
GGML_API size_t ggml_nbytes_split(const struct ggml_tensor * tensor, int nrows_split);
|
471 |
+
|
472 |
+
GGML_API int ggml_blck_size (enum ggml_type type);
|
473 |
+
GGML_API size_t ggml_type_size (enum ggml_type type); // size in bytes for all elements in a block
|
474 |
+
GGML_API float ggml_type_sizef(enum ggml_type type); // ggml_type_size()/ggml_blck_size() as float
|
475 |
+
|
476 |
+
GGML_API const char * ggml_type_name(enum ggml_type type);
|
477 |
+
GGML_API const char * ggml_op_name (enum ggml_op op);
|
478 |
+
|
479 |
+
GGML_API size_t ggml_element_size(const struct ggml_tensor * tensor);
|
480 |
+
|
481 |
+
GGML_API bool ggml_is_quantized(enum ggml_type type);
|
482 |
+
|
483 |
+
// TODO: temporary until model loading of ggml examples is refactored
|
484 |
+
GGML_API enum ggml_type ggml_ftype_to_ggml_type(enum ggml_ftype ftype);
|
485 |
+
|
486 |
+
GGML_API bool ggml_is_transposed(const struct ggml_tensor * tensor);
|
487 |
+
GGML_API bool ggml_is_contiguous(const struct ggml_tensor * tensor);
|
488 |
+
GGML_API bool ggml_is_permuted (const struct ggml_tensor * tensor);
|
489 |
+
|
490 |
+
// use this to compute the memory overhead of a tensor
|
491 |
+
GGML_API size_t ggml_tensor_overhead(void);
|
492 |
+
|
493 |
+
// main
|
494 |
+
|
495 |
+
GGML_API struct ggml_context * ggml_init(struct ggml_init_params params);
|
496 |
+
GGML_API void ggml_free(struct ggml_context * ctx);
|
497 |
+
|
498 |
+
GGML_API size_t ggml_used_mem(const struct ggml_context * ctx);
|
499 |
+
|
500 |
+
GGML_API size_t ggml_set_scratch (struct ggml_context * ctx, struct ggml_scratch scratch);
|
501 |
+
GGML_API void ggml_set_no_alloc(struct ggml_context * ctx, bool no_alloc);
|
502 |
+
|
503 |
+
GGML_API void * ggml_get_mem_buffer(struct ggml_context * ctx);
|
504 |
+
GGML_API size_t ggml_get_mem_size (struct ggml_context * ctx);
|
505 |
+
|
506 |
+
GGML_API struct ggml_tensor * ggml_new_tensor(
|
507 |
+
struct ggml_context * ctx,
|
508 |
+
enum ggml_type type,
|
509 |
+
int n_dims,
|
510 |
+
const int64_t *ne);
|
511 |
+
|
512 |
+
GGML_API struct ggml_tensor * ggml_new_tensor_1d(
|
513 |
+
struct ggml_context * ctx,
|
514 |
+
enum ggml_type type,
|
515 |
+
int64_t ne0);
|
516 |
+
|
517 |
+
GGML_API struct ggml_tensor * ggml_new_tensor_2d(
|
518 |
+
struct ggml_context * ctx,
|
519 |
+
enum ggml_type type,
|
520 |
+
int64_t ne0,
|
521 |
+
int64_t ne1);
|
522 |
+
|
523 |
+
GGML_API struct ggml_tensor * ggml_new_tensor_3d(
|
524 |
+
struct ggml_context * ctx,
|
525 |
+
enum ggml_type type,
|
526 |
+
int64_t ne0,
|
527 |
+
int64_t ne1,
|
528 |
+
int64_t ne2);
|
529 |
+
|
530 |
+
GGML_API struct ggml_tensor * ggml_new_tensor_4d(
|
531 |
+
struct ggml_context * ctx,
|
532 |
+
enum ggml_type type,
|
533 |
+
int64_t ne0,
|
534 |
+
int64_t ne1,
|
535 |
+
int64_t ne2,
|
536 |
+
int64_t ne3);
|
537 |
+
|
538 |
+
GGML_API struct ggml_tensor * ggml_new_i32(struct ggml_context * ctx, int32_t value);
|
539 |
+
GGML_API struct ggml_tensor * ggml_new_f32(struct ggml_context * ctx, float value);
|
540 |
+
|
541 |
+
GGML_API struct ggml_tensor * ggml_dup_tensor (struct ggml_context * ctx, const struct ggml_tensor * src);
|
542 |
+
GGML_API struct ggml_tensor * ggml_view_tensor(struct ggml_context * ctx, const struct ggml_tensor * src);
|
543 |
+
|
544 |
+
GGML_API struct ggml_tensor * ggml_get_tensor(struct ggml_context * ctx, const char * name);
|
545 |
+
|
546 |
+
GGML_API struct ggml_tensor * ggml_set_zero(struct ggml_tensor * tensor);
|
547 |
+
GGML_API struct ggml_tensor * ggml_set_i32 (struct ggml_tensor * tensor, int32_t value);
|
548 |
+
GGML_API struct ggml_tensor * ggml_set_f32 (struct ggml_tensor * tensor, float value);
|
549 |
+
|
550 |
+
GGML_API int32_t ggml_get_i32_1d(const struct ggml_tensor * tensor, int i);
|
551 |
+
GGML_API void ggml_set_i32_1d(const struct ggml_tensor * tensor, int i, int32_t value);
|
552 |
+
|
553 |
+
GGML_API float ggml_get_f32_1d(const struct ggml_tensor * tensor, int i);
|
554 |
+
GGML_API void ggml_set_f32_1d(const struct ggml_tensor * tensor, int i, float value);
|
555 |
+
|
556 |
+
GGML_API void * ggml_get_data (const struct ggml_tensor * tensor);
|
557 |
+
GGML_API float * ggml_get_data_f32(const struct ggml_tensor * tensor);
|
558 |
+
|
559 |
+
GGML_API const char * ggml_get_name(const struct ggml_tensor * tensor);
|
560 |
+
GGML_API void ggml_set_name(struct ggml_tensor * tensor, const char * name);
|
561 |
+
|
562 |
+
//
|
563 |
+
// operations on tensors with backpropagation
|
564 |
+
//
|
565 |
+
|
566 |
+
GGML_API struct ggml_tensor * ggml_dup(
|
567 |
+
struct ggml_context * ctx,
|
568 |
+
struct ggml_tensor * a);
|
569 |
+
|
570 |
+
GGML_API struct ggml_tensor * ggml_add(
|
571 |
+
struct ggml_context * ctx,
|
572 |
+
struct ggml_tensor * a,
|
573 |
+
struct ggml_tensor * b);
|
574 |
+
|
575 |
+
GGML_API struct ggml_tensor * ggml_add_inplace(
|
576 |
+
struct ggml_context * ctx,
|
577 |
+
struct ggml_tensor * a,
|
578 |
+
struct ggml_tensor * b);
|
579 |
+
|
580 |
+
GGML_API struct ggml_tensor * ggml_add1(
|
581 |
+
struct ggml_context * ctx,
|
582 |
+
struct ggml_tensor * a,
|
583 |
+
struct ggml_tensor * b);
|
584 |
+
|
585 |
+
GGML_API struct ggml_tensor * ggml_add1_inplace(
|
586 |
+
struct ggml_context * ctx,
|
587 |
+
struct ggml_tensor * a,
|
588 |
+
struct ggml_tensor * b);
|
589 |
+
|
590 |
+
GGML_API struct ggml_tensor * ggml_acc(
|
591 |
+
struct ggml_context * ctx,
|
592 |
+
struct ggml_tensor * a,
|
593 |
+
struct ggml_tensor * b,
|
594 |
+
size_t nb1,
|
595 |
+
size_t nb2,
|
596 |
+
size_t nb3,
|
597 |
+
size_t offset);
|
598 |
+
|
599 |
+
GGML_API struct ggml_tensor * ggml_acc_inplace(
|
600 |
+
struct ggml_context * ctx,
|
601 |
+
struct ggml_tensor * a,
|
602 |
+
struct ggml_tensor * b,
|
603 |
+
size_t nb1,
|
604 |
+
size_t nb2,
|
605 |
+
size_t nb3,
|
606 |
+
size_t offset);
|
607 |
+
|
608 |
+
GGML_API struct ggml_tensor * ggml_sub(
|
609 |
+
struct ggml_context * ctx,
|
610 |
+
struct ggml_tensor * a,
|
611 |
+
struct ggml_tensor * b);
|
612 |
+
|
613 |
+
GGML_API struct ggml_tensor * ggml_mul(
|
614 |
+
struct ggml_context * ctx,
|
615 |
+
struct ggml_tensor * a,
|
616 |
+
struct ggml_tensor * b);
|
617 |
+
|
618 |
+
GGML_API struct ggml_tensor * ggml_div(
|
619 |
+
struct ggml_context * ctx,
|
620 |
+
struct ggml_tensor * a,
|
621 |
+
struct ggml_tensor * b);
|
622 |
+
|
623 |
+
GGML_API struct ggml_tensor * ggml_sqr(
|
624 |
+
struct ggml_context * ctx,
|
625 |
+
struct ggml_tensor * a);
|
626 |
+
|
627 |
+
GGML_API struct ggml_tensor * ggml_sqrt(
|
628 |
+
struct ggml_context * ctx,
|
629 |
+
struct ggml_tensor * a);
|
630 |
+
|
631 |
+
GGML_API struct ggml_tensor * ggml_log(
|
632 |
+
struct ggml_context * ctx,
|
633 |
+
struct ggml_tensor * a);
|
634 |
+
|
635 |
+
GGML_API struct ggml_tensor * ggml_log_inplace(
|
636 |
+
struct ggml_context * ctx,
|
637 |
+
struct ggml_tensor * a);
|
638 |
+
|
639 |
+
// return scalar
|
640 |
+
GGML_API struct ggml_tensor * ggml_sum(
|
641 |
+
struct ggml_context * ctx,
|
642 |
+
struct ggml_tensor * a);
|
643 |
+
|
644 |
+
// sums along rows, with input shape [a,b,c,d] return shape [1,b,c,d]
|
645 |
+
GGML_API struct ggml_tensor * ggml_sum_rows(
|
646 |
+
struct ggml_context * ctx,
|
647 |
+
struct ggml_tensor * a);
|
648 |
+
|
649 |
+
// mean along rows
|
650 |
+
GGML_API struct ggml_tensor * ggml_mean(
|
651 |
+
struct ggml_context * ctx,
|
652 |
+
struct ggml_tensor * a);
|
653 |
+
|
654 |
+
// if a is the same shape as b, and a is not parameter, return a
|
655 |
+
// otherwise, return a new tensor: repeat(a) to fit in b
|
656 |
+
GGML_API struct ggml_tensor * ggml_repeat(
|
657 |
+
struct ggml_context * ctx,
|
658 |
+
struct ggml_tensor * a,
|
659 |
+
struct ggml_tensor * b);
|
660 |
+
|
661 |
+
GGML_API struct ggml_tensor * ggml_repeat_back(
|
662 |
+
struct ggml_context * ctx,
|
663 |
+
struct ggml_tensor * a,
|
664 |
+
struct ggml_tensor * b);
|
665 |
+
|
666 |
+
GGML_API struct ggml_tensor * ggml_abs(
|
667 |
+
struct ggml_context * ctx,
|
668 |
+
struct ggml_tensor * a);
|
669 |
+
|
670 |
+
GGML_API struct ggml_tensor * ggml_sgn(
|
671 |
+
struct ggml_context * ctx,
|
672 |
+
struct ggml_tensor * a);
|
673 |
+
|
674 |
+
GGML_API struct ggml_tensor * ggml_neg(
|
675 |
+
struct ggml_context * ctx,
|
676 |
+
struct ggml_tensor * a);
|
677 |
+
|
678 |
+
GGML_API struct ggml_tensor * ggml_step(
|
679 |
+
struct ggml_context * ctx,
|
680 |
+
struct ggml_tensor * a);
|
681 |
+
|
682 |
+
GGML_API struct ggml_tensor * ggml_relu(
|
683 |
+
struct ggml_context * ctx,
|
684 |
+
struct ggml_tensor * a);
|
685 |
+
|
686 |
+
// TODO: double-check this computation is correct
|
687 |
+
GGML_API struct ggml_tensor * ggml_gelu(
|
688 |
+
struct ggml_context * ctx,
|
689 |
+
struct ggml_tensor * a);
|
690 |
+
|
691 |
+
GGML_API struct ggml_tensor * ggml_silu(
|
692 |
+
struct ggml_context * ctx,
|
693 |
+
struct ggml_tensor * a);
|
694 |
+
|
695 |
+
// a - x
|
696 |
+
// b - dy
|
697 |
+
GGML_API struct ggml_tensor * ggml_silu_back(
|
698 |
+
struct ggml_context * ctx,
|
699 |
+
struct ggml_tensor * a,
|
700 |
+
struct ggml_tensor * b);
|
701 |
+
|
702 |
+
// normalize along rows
|
703 |
+
// TODO: eps is hardcoded to 1e-5 for now
|
704 |
+
GGML_API struct ggml_tensor * ggml_norm(
|
705 |
+
struct ggml_context * ctx,
|
706 |
+
struct ggml_tensor * a);
|
707 |
+
|
708 |
+
GGML_API struct ggml_tensor * ggml_rms_norm(
|
709 |
+
struct ggml_context * ctx,
|
710 |
+
struct ggml_tensor * a);
|
711 |
+
|
712 |
+
// a - x
|
713 |
+
// b - dy
|
714 |
+
GGML_API struct ggml_tensor * ggml_rms_norm_back(
|
715 |
+
struct ggml_context * ctx,
|
716 |
+
struct ggml_tensor * a,
|
717 |
+
struct ggml_tensor * b);
|
718 |
+
|
719 |
+
// A: n columns, m rows
|
720 |
+
// B: n columns, p rows (i.e. we transpose it internally)
|
721 |
+
// result is m columns, p rows
|
722 |
+
GGML_API struct ggml_tensor * ggml_mul_mat(
|
723 |
+
struct ggml_context * ctx,
|
724 |
+
struct ggml_tensor * a,
|
725 |
+
struct ggml_tensor * b);
|
726 |
+
|
727 |
+
// A: m columns, n rows,
|
728 |
+
// B: p columns, n rows,
|
729 |
+
// result is m columns, p rows
|
730 |
+
GGML_API struct ggml_tensor * ggml_out_prod(
|
731 |
+
struct ggml_context * ctx,
|
732 |
+
struct ggml_tensor * a,
|
733 |
+
struct ggml_tensor * b);
|
734 |
+
|
735 |
+
//
|
736 |
+
// operations on tensors without backpropagation
|
737 |
+
//
|
738 |
+
|
739 |
+
GGML_API struct ggml_tensor * ggml_scale(
|
740 |
+
struct ggml_context * ctx,
|
741 |
+
struct ggml_tensor * a,
|
742 |
+
struct ggml_tensor * b);
|
743 |
+
|
744 |
+
// in-place, returns view(a)
|
745 |
+
GGML_API struct ggml_tensor * ggml_scale_inplace(
|
746 |
+
struct ggml_context * ctx,
|
747 |
+
struct ggml_tensor * a,
|
748 |
+
struct ggml_tensor * b);
|
749 |
+
|
750 |
+
// b -> view(a,offset,nb1,nb2,3), return modified a
|
751 |
+
GGML_API struct ggml_tensor * ggml_set(
|
752 |
+
struct ggml_context * ctx,
|
753 |
+
struct ggml_tensor * a,
|
754 |
+
struct ggml_tensor * b,
|
755 |
+
size_t nb1,
|
756 |
+
size_t nb2,
|
757 |
+
size_t nb3,
|
758 |
+
size_t offset);
|
759 |
+
|
760 |
+
// b -> view(a,offset,nb1,nb2,3), return view(a)
|
761 |
+
GGML_API struct ggml_tensor * ggml_set_inplace(
|
762 |
+
struct ggml_context * ctx,
|
763 |
+
struct ggml_tensor * a,
|
764 |
+
struct ggml_tensor * b,
|
765 |
+
size_t nb1,
|
766 |
+
size_t nb2,
|
767 |
+
size_t nb3,
|
768 |
+
size_t offset);
|
769 |
+
|
770 |
+
GGML_API struct ggml_tensor * ggml_set_1d(
|
771 |
+
struct ggml_context * ctx,
|
772 |
+
struct ggml_tensor * a,
|
773 |
+
struct ggml_tensor * b,
|
774 |
+
size_t offset);
|
775 |
+
|
776 |
+
GGML_API struct ggml_tensor * ggml_set_1d_inplace(
|
777 |
+
struct ggml_context * ctx,
|
778 |
+
struct ggml_tensor * a,
|
779 |
+
struct ggml_tensor * b,
|
780 |
+
size_t offset);
|
781 |
+
|
782 |
+
// b -> view(a,offset,nb1,nb2,3), return modified a
|
783 |
+
GGML_API struct ggml_tensor * ggml_set_2d(
|
784 |
+
struct ggml_context * ctx,
|
785 |
+
struct ggml_tensor * a,
|
786 |
+
struct ggml_tensor * b,
|
787 |
+
size_t nb1,
|
788 |
+
size_t offset);
|
789 |
+
|
790 |
+
// b -> view(a,offset,nb1,nb2,3), return view(a)
|
791 |
+
GGML_API struct ggml_tensor * ggml_set_2d_inplace(
|
792 |
+
struct ggml_context * ctx,
|
793 |
+
struct ggml_tensor * a,
|
794 |
+
struct ggml_tensor * b,
|
795 |
+
size_t nb1,
|
796 |
+
size_t offset);
|
797 |
+
|
798 |
+
|
799 |
+
// a -> b, return view(b)
|
800 |
+
GGML_API struct ggml_tensor * ggml_cpy(
|
801 |
+
struct ggml_context * ctx,
|
802 |
+
struct ggml_tensor * a,
|
803 |
+
struct ggml_tensor * b);
|
804 |
+
|
805 |
+
// make contiguous
|
806 |
+
GGML_API struct ggml_tensor * ggml_cont(
|
807 |
+
struct ggml_context * ctx,
|
808 |
+
struct ggml_tensor * a);
|
809 |
+
|
810 |
+
// return view(a), b specifies the new shape
|
811 |
+
// TODO: when we start computing gradient, make a copy instead of view
|
812 |
+
GGML_API struct ggml_tensor * ggml_reshape(
|
813 |
+
struct ggml_context * ctx,
|
814 |
+
struct ggml_tensor * a,
|
815 |
+
struct ggml_tensor * b);
|
816 |
+
|
817 |
+
// return view(a)
|
818 |
+
// TODO: when we start computing gradient, make a copy instead of view
|
819 |
+
GGML_API struct ggml_tensor * ggml_reshape_1d(
|
820 |
+
struct ggml_context * ctx,
|
821 |
+
struct ggml_tensor * a,
|
822 |
+
int64_t ne0);
|
823 |
+
|
824 |
+
GGML_API struct ggml_tensor * ggml_reshape_2d(
|
825 |
+
struct ggml_context * ctx,
|
826 |
+
struct ggml_tensor * a,
|
827 |
+
int64_t ne0,
|
828 |
+
int64_t ne1);
|
829 |
+
|
830 |
+
// return view(a)
|
831 |
+
// TODO: when we start computing gradient, make a copy instead of view
|
832 |
+
GGML_API struct ggml_tensor * ggml_reshape_3d(
|
833 |
+
struct ggml_context * ctx,
|
834 |
+
struct ggml_tensor * a,
|
835 |
+
int64_t ne0,
|
836 |
+
int64_t ne1,
|
837 |
+
int64_t ne2);
|
838 |
+
|
839 |
+
GGML_API struct ggml_tensor * ggml_reshape_4d(
|
840 |
+
struct ggml_context * ctx,
|
841 |
+
struct ggml_tensor * a,
|
842 |
+
int64_t ne0,
|
843 |
+
int64_t ne1,
|
844 |
+
int64_t ne2,
|
845 |
+
int64_t ne3);
|
846 |
+
|
847 |
+
// offset in bytes
|
848 |
+
GGML_API struct ggml_tensor * ggml_view_1d(
|
849 |
+
struct ggml_context * ctx,
|
850 |
+
struct ggml_tensor * a,
|
851 |
+
int64_t ne0,
|
852 |
+
size_t offset);
|
853 |
+
|
854 |
+
GGML_API struct ggml_tensor * ggml_view_2d(
|
855 |
+
struct ggml_context * ctx,
|
856 |
+
struct ggml_tensor * a,
|
857 |
+
int64_t ne0,
|
858 |
+
int64_t ne1,
|
859 |
+
size_t nb1, // row stride in bytes
|
860 |
+
size_t offset);
|
861 |
+
|
862 |
+
GGML_API struct ggml_tensor * ggml_view_3d(
|
863 |
+
struct ggml_context * ctx,
|
864 |
+
struct ggml_tensor * a,
|
865 |
+
int64_t ne0,
|
866 |
+
int64_t ne1,
|
867 |
+
int64_t ne2,
|
868 |
+
size_t nb1, // row stride in bytes
|
869 |
+
size_t nb2, // slice stride in bytes
|
870 |
+
size_t offset);
|
871 |
+
|
872 |
+
GGML_API struct ggml_tensor * ggml_view_4d(
|
873 |
+
struct ggml_context * ctx,
|
874 |
+
struct ggml_tensor * a,
|
875 |
+
int64_t ne0,
|
876 |
+
int64_t ne1,
|
877 |
+
int64_t ne2,
|
878 |
+
int64_t ne3,
|
879 |
+
size_t nb1, // row stride in bytes
|
880 |
+
size_t nb2, // slice stride in bytes
|
881 |
+
size_t nb3,
|
882 |
+
size_t offset);
|
883 |
+
|
884 |
+
GGML_API struct ggml_tensor * ggml_permute(
|
885 |
+
struct ggml_context * ctx,
|
886 |
+
struct ggml_tensor * a,
|
887 |
+
int axis0,
|
888 |
+
int axis1,
|
889 |
+
int axis2,
|
890 |
+
int axis3);
|
891 |
+
|
892 |
+
// alias for ggml_permute(ctx, a, 1, 0, 2, 3)
|
893 |
+
GGML_API struct ggml_tensor * ggml_transpose(
|
894 |
+
struct ggml_context * ctx,
|
895 |
+
struct ggml_tensor * a);
|
896 |
+
|
897 |
+
GGML_API struct ggml_tensor * ggml_get_rows(
|
898 |
+
struct ggml_context * ctx,
|
899 |
+
struct ggml_tensor * a,
|
900 |
+
struct ggml_tensor * b);
|
901 |
+
|
902 |
+
GGML_API struct ggml_tensor * ggml_get_rows_back(
|
903 |
+
struct ggml_context * ctx,
|
904 |
+
struct ggml_tensor * a,
|
905 |
+
struct ggml_tensor * b,
|
906 |
+
struct ggml_tensor * c);
|
907 |
+
|
908 |
+
GGML_API struct ggml_tensor * ggml_diag(
|
909 |
+
struct ggml_context * ctx,
|
910 |
+
struct ggml_tensor * a);
|
911 |
+
|
912 |
+
// set elements above the diagonal to -INF
|
913 |
+
GGML_API struct ggml_tensor * ggml_diag_mask_inf(
|
914 |
+
struct ggml_context * ctx,
|
915 |
+
struct ggml_tensor * a,
|
916 |
+
int n_past);
|
917 |
+
|
918 |
+
// in-place, returns view(a)
|
919 |
+
GGML_API struct ggml_tensor * ggml_diag_mask_inf_inplace(
|
920 |
+
struct ggml_context * ctx,
|
921 |
+
struct ggml_tensor * a,
|
922 |
+
int n_past);
|
923 |
+
|
924 |
+
// set elements above the diagonal to 0
|
925 |
+
GGML_API struct ggml_tensor * ggml_diag_mask_zero(
|
926 |
+
struct ggml_context * ctx,
|
927 |
+
struct ggml_tensor * a,
|
928 |
+
int n_past);
|
929 |
+
|
930 |
+
// in-place, returns view(a)
|
931 |
+
GGML_API struct ggml_tensor * ggml_diag_mask_zero_inplace(
|
932 |
+
struct ggml_context * ctx,
|
933 |
+
struct ggml_tensor * a,
|
934 |
+
int n_past);
|
935 |
+
|
936 |
+
GGML_API struct ggml_tensor * ggml_soft_max(
|
937 |
+
struct ggml_context * ctx,
|
938 |
+
struct ggml_tensor * a);
|
939 |
+
|
940 |
+
// in-place, returns view(a)
|
941 |
+
GGML_API struct ggml_tensor * ggml_soft_max_inplace(
|
942 |
+
struct ggml_context * ctx,
|
943 |
+
struct ggml_tensor * a);
|
944 |
+
|
945 |
+
GGML_API struct ggml_tensor * ggml_soft_max_back(
|
946 |
+
struct ggml_context * ctx,
|
947 |
+
struct ggml_tensor * a,
|
948 |
+
struct ggml_tensor * b);
|
949 |
+
|
950 |
+
// in-place, returns view(a)
|
951 |
+
GGML_API struct ggml_tensor * ggml_soft_max_back_inplace(
|
952 |
+
struct ggml_context * ctx,
|
953 |
+
struct ggml_tensor * a,
|
954 |
+
struct ggml_tensor * b);
|
955 |
+
|
956 |
+
// rotary position embedding
|
957 |
+
// if mode & 1 == 1, skip n_past elements
|
958 |
+
// if mode & 2 == 1, GPT-NeoX style
|
959 |
+
// TODO: avoid creating a new tensor every time
|
960 |
+
GGML_API struct ggml_tensor * ggml_rope(
|
961 |
+
struct ggml_context * ctx,
|
962 |
+
struct ggml_tensor * a,
|
963 |
+
int n_past,
|
964 |
+
int n_dims,
|
965 |
+
int mode);
|
966 |
+
|
967 |
+
// in-place, returns view(a)
|
968 |
+
GGML_API struct ggml_tensor * ggml_rope_inplace(
|
969 |
+
struct ggml_context * ctx,
|
970 |
+
struct ggml_tensor * a,
|
971 |
+
int n_past,
|
972 |
+
int n_dims,
|
973 |
+
int mode);
|
974 |
+
|
975 |
+
// rotary position embedding backward, i.e compute dx from dy
|
976 |
+
// a - dy
|
977 |
+
GGML_API struct ggml_tensor * ggml_rope_back(
|
978 |
+
struct ggml_context * ctx,
|
979 |
+
struct ggml_tensor * a,
|
980 |
+
int n_past,
|
981 |
+
int n_dims,
|
982 |
+
int mode);
|
983 |
+
|
984 |
+
// alibi position embedding
|
985 |
+
// in-place, returns view(a)
|
986 |
+
struct ggml_tensor * ggml_alibi(
|
987 |
+
struct ggml_context * ctx,
|
988 |
+
struct ggml_tensor * a,
|
989 |
+
int n_past,
|
990 |
+
int n_head,
|
991 |
+
float bias_max);
|
992 |
+
|
993 |
+
// clamp
|
994 |
+
// in-place, returns view(a)
|
995 |
+
struct ggml_tensor * ggml_clamp(
|
996 |
+
struct ggml_context * ctx,
|
997 |
+
struct ggml_tensor * a,
|
998 |
+
float min,
|
999 |
+
float max);
|
1000 |
+
|
1001 |
+
// padding = 1
|
1002 |
+
// TODO: we don't support extra parameters for now
|
1003 |
+
// that's why we are hard-coding the stride, padding, and dilation
|
1004 |
+
// not great ..
|
1005 |
+
GGML_API struct ggml_tensor * ggml_conv_1d_1s(
|
1006 |
+
struct ggml_context * ctx,
|
1007 |
+
struct ggml_tensor * a,
|
1008 |
+
struct ggml_tensor * b);
|
1009 |
+
|
1010 |
+
GGML_API struct ggml_tensor * ggml_conv_1d_2s(
|
1011 |
+
struct ggml_context * ctx,
|
1012 |
+
struct ggml_tensor * a,
|
1013 |
+
struct ggml_tensor * b);
|
1014 |
+
|
1015 |
+
GGML_API struct ggml_tensor * ggml_flash_attn(
|
1016 |
+
struct ggml_context * ctx,
|
1017 |
+
struct ggml_tensor * q,
|
1018 |
+
struct ggml_tensor * k,
|
1019 |
+
struct ggml_tensor * v,
|
1020 |
+
bool masked);
|
1021 |
+
|
1022 |
+
GGML_API struct ggml_tensor * ggml_flash_attn_back(
|
1023 |
+
struct ggml_context * ctx,
|
1024 |
+
struct ggml_tensor * q,
|
1025 |
+
struct ggml_tensor * k,
|
1026 |
+
struct ggml_tensor * v,
|
1027 |
+
struct ggml_tensor * d,
|
1028 |
+
bool masked);
|
1029 |
+
|
1030 |
+
GGML_API struct ggml_tensor * ggml_flash_ff(
|
1031 |
+
struct ggml_context * ctx,
|
1032 |
+
struct ggml_tensor * a,
|
1033 |
+
struct ggml_tensor * b0,
|
1034 |
+
struct ggml_tensor * b1,
|
1035 |
+
struct ggml_tensor * c0,
|
1036 |
+
struct ggml_tensor * c1);
|
1037 |
+
|
1038 |
+
// Mapping operations
|
1039 |
+
typedef void (*ggml_unary_op_f32_t)(const int, float *, const float *);
|
1040 |
+
typedef void (*ggml_binary_op_f32_t)(const int, float *, const float *, const float *);
|
1041 |
+
|
1042 |
+
GGML_API struct ggml_tensor * ggml_map_unary_f32(
|
1043 |
+
struct ggml_context * ctx,
|
1044 |
+
struct ggml_tensor * a,
|
1045 |
+
ggml_unary_op_f32_t fun);
|
1046 |
+
|
1047 |
+
GGML_API struct ggml_tensor * ggml_map_binary_f32(
|
1048 |
+
struct ggml_context * ctx,
|
1049 |
+
struct ggml_tensor * a,
|
1050 |
+
struct ggml_tensor * b,
|
1051 |
+
ggml_binary_op_f32_t fun);
|
1052 |
+
|
1053 |
+
// loss function
|
1054 |
+
|
1055 |
+
GGML_API struct ggml_tensor * ggml_cross_entropy_loss(
|
1056 |
+
struct ggml_context * ctx,
|
1057 |
+
struct ggml_tensor * a,
|
1058 |
+
struct ggml_tensor * b);
|
1059 |
+
|
1060 |
+
GGML_API struct ggml_tensor * ggml_cross_entropy_loss_back(
|
1061 |
+
struct ggml_context * ctx,
|
1062 |
+
struct ggml_tensor * a,
|
1063 |
+
struct ggml_tensor * b,
|
1064 |
+
struct ggml_tensor * c);
|
1065 |
+
|
1066 |
+
//
|
1067 |
+
// automatic differentiation
|
1068 |
+
//
|
1069 |
+
|
1070 |
+
GGML_API void ggml_set_param(
|
1071 |
+
struct ggml_context * ctx,
|
1072 |
+
struct ggml_tensor * tensor);
|
1073 |
+
|
1074 |
+
GGML_API void ggml_build_forward_expand(struct ggml_cgraph * cgraph, struct ggml_tensor * tensor);
|
1075 |
+
|
1076 |
+
GGML_API struct ggml_cgraph ggml_build_forward (struct ggml_tensor * tensor);
|
1077 |
+
GGML_API struct ggml_cgraph ggml_build_backward(struct ggml_context * ctx, struct ggml_cgraph * gf, bool keep);
|
1078 |
+
|
1079 |
+
GGML_API void ggml_graph_compute(struct ggml_context * ctx, struct ggml_cgraph * cgraph);
|
1080 |
+
GGML_API void ggml_graph_reset (struct ggml_cgraph * cgraph);
|
1081 |
+
|
1082 |
+
GGML_API struct ggml_tensor * ggml_graph_get_tensor(struct ggml_cgraph * cgraph, const char * name);
|
1083 |
+
|
1084 |
+
GGML_API void ggml_graph_export(const struct ggml_cgraph * cgraph, const char * fname);
|
1085 |
+
GGML_API struct ggml_cgraph ggml_graph_import(const char * fname, struct ggml_context ** ctx_data, struct ggml_context ** ctx_eval);
|
1086 |
+
|
1087 |
+
// print info and performance information for the graph
|
1088 |
+
GGML_API void ggml_graph_print(const struct ggml_cgraph * cgraph);
|
1089 |
+
|
1090 |
+
// dump the graph into a file using the dot format
|
1091 |
+
GGML_API void ggml_graph_dump_dot(const struct ggml_cgraph * gb, const struct ggml_cgraph * gf, const char * filename);
|
1092 |
+
|
1093 |
+
//
|
1094 |
+
// optimization
|
1095 |
+
//
|
1096 |
+
|
1097 |
+
// optimization methods
|
1098 |
+
enum ggml_opt_type {
|
1099 |
+
GGML_OPT_ADAM,
|
1100 |
+
GGML_OPT_LBFGS,
|
1101 |
+
};
|
1102 |
+
|
1103 |
+
// linesearch methods
|
1104 |
+
enum ggml_linesearch {
|
1105 |
+
GGML_LINESEARCH_DEFAULT = 1,
|
1106 |
+
|
1107 |
+
GGML_LINESEARCH_BACKTRACKING_ARMIJO = 0,
|
1108 |
+
GGML_LINESEARCH_BACKTRACKING_WOLFE = 1,
|
1109 |
+
GGML_LINESEARCH_BACKTRACKING_STRONG_WOLFE = 2,
|
1110 |
+
};
|
1111 |
+
|
1112 |
+
// optimization return values
|
1113 |
+
enum ggml_opt_result {
|
1114 |
+
GGML_OPT_OK = 0,
|
1115 |
+
GGML_OPT_DID_NOT_CONVERGE,
|
1116 |
+
GGML_OPT_NO_CONTEXT,
|
1117 |
+
GGML_OPT_INVALID_WOLFE,
|
1118 |
+
GGML_OPT_FAIL,
|
1119 |
+
|
1120 |
+
GGML_LINESEARCH_FAIL = -128,
|
1121 |
+
GGML_LINESEARCH_MINIMUM_STEP,
|
1122 |
+
GGML_LINESEARCH_MAXIMUM_STEP,
|
1123 |
+
GGML_LINESEARCH_MAXIMUM_ITERATIONS,
|
1124 |
+
GGML_LINESEARCH_INVALID_PARAMETERS,
|
1125 |
+
};
|
1126 |
+
|
1127 |
+
// optimization parameters
|
1128 |
+
//
|
1129 |
+
// see ggml.c (ggml_opt_default_params) for default values
|
1130 |
+
//
|
1131 |
+
struct ggml_opt_params {
|
1132 |
+
enum ggml_opt_type type;
|
1133 |
+
|
1134 |
+
int n_threads;
|
1135 |
+
|
1136 |
+
// delta-based convergence test
|
1137 |
+
//
|
1138 |
+
// if past == 0 - disabled
|
1139 |
+
// if past > 0:
|
1140 |
+
// stop if |f(x) - f(x_past)| < delta * max(1, |f(x)|)
|
1141 |
+
//
|
1142 |
+
int past;
|
1143 |
+
float delta;
|
1144 |
+
|
1145 |
+
// maximum number of iterations without improvement
|
1146 |
+
//
|
1147 |
+
// if 0 - disabled
|
1148 |
+
// if > 0:
|
1149 |
+
// assume convergence if no cost improvement in this number of iterations
|
1150 |
+
//
|
1151 |
+
int max_no_improvement;
|
1152 |
+
|
1153 |
+
bool print_forward_graph;
|
1154 |
+
bool print_backward_graph;
|
1155 |
+
|
1156 |
+
// ADAM parameters
|
1157 |
+
struct {
|
1158 |
+
int n_iter;
|
1159 |
+
|
1160 |
+
float sched; // schedule multiplier (fixed, decay or warmup)
|
1161 |
+
float decay; // weight decay for AdamW, use 0.0f to disable
|
1162 |
+
float alpha; // learning rate
|
1163 |
+
float beta1;
|
1164 |
+
float beta2;
|
1165 |
+
float eps; // epsilon for numerical stability
|
1166 |
+
float eps_f; // epsilon for convergence test
|
1167 |
+
float eps_g; // epsilon for convergence test
|
1168 |
+
} adam;
|
1169 |
+
|
1170 |
+
// LBFGS parameters
|
1171 |
+
struct {
|
1172 |
+
int m; // number of corrections to approximate the inv. Hessian
|
1173 |
+
int n_iter;
|
1174 |
+
int max_linesearch;
|
1175 |
+
|
1176 |
+
float eps; // convergence tolerance
|
1177 |
+
float ftol; // line search tolerance
|
1178 |
+
float wolfe;
|
1179 |
+
float min_step;
|
1180 |
+
float max_step;
|
1181 |
+
|
1182 |
+
enum ggml_linesearch linesearch;
|
1183 |
+
} lbfgs;
|
1184 |
+
};
|
1185 |
+
|
1186 |
+
struct ggml_opt_context {
|
1187 |
+
struct ggml_context * ctx;
|
1188 |
+
struct ggml_opt_params params;
|
1189 |
+
|
1190 |
+
int iter;
|
1191 |
+
int64_t nx; // number of parameter elements
|
1192 |
+
|
1193 |
+
bool just_initialized;
|
1194 |
+
|
1195 |
+
struct {
|
1196 |
+
struct ggml_tensor * x; // view of the parameters
|
1197 |
+
struct ggml_tensor * g1; // gradient
|
1198 |
+
struct ggml_tensor * g2; // gradient squared
|
1199 |
+
struct ggml_tensor * m; // first moment
|
1200 |
+
struct ggml_tensor * v; // second moment
|
1201 |
+
struct ggml_tensor * mh; // first moment hat
|
1202 |
+
struct ggml_tensor * vh; // second moment hat
|
1203 |
+
struct ggml_tensor * pf; // past function values
|
1204 |
+
float fx_best;
|
1205 |
+
float fx_prev;
|
1206 |
+
int n_no_improvement;
|
1207 |
+
} adam;
|
1208 |
+
|
1209 |
+
struct {
|
1210 |
+
struct ggml_tensor * x; // current parameters
|
1211 |
+
struct ggml_tensor * xp; // previous parameters
|
1212 |
+
struct ggml_tensor * g; // current gradient
|
1213 |
+
struct ggml_tensor * gp; // previous gradient
|
1214 |
+
struct ggml_tensor * d; // search direction
|
1215 |
+
struct ggml_tensor * pf; // past function values
|
1216 |
+
struct ggml_tensor * lmal; // the L-BFGS memory alpha
|
1217 |
+
struct ggml_tensor * lmys; // the L-BFGS memory ys
|
1218 |
+
struct ggml_tensor * lms; // the L-BFGS memory s
|
1219 |
+
struct ggml_tensor * lmy; // the L-BFGS memory y
|
1220 |
+
float fx_best;
|
1221 |
+
float step;
|
1222 |
+
int j;
|
1223 |
+
int k;
|
1224 |
+
int end;
|
1225 |
+
int n_no_improvement;
|
1226 |
+
} lbfgs;
|
1227 |
+
};
|
1228 |
+
|
1229 |
+
GGML_API struct ggml_opt_params ggml_opt_default_params(enum ggml_opt_type type);
|
1230 |
+
|
1231 |
+
// optimize the function defined by the tensor f
|
1232 |
+
GGML_API enum ggml_opt_result ggml_opt(
|
1233 |
+
struct ggml_context * ctx,
|
1234 |
+
struct ggml_opt_params params,
|
1235 |
+
struct ggml_tensor * f);
|
1236 |
+
|
1237 |
+
// initialize optimizer context
|
1238 |
+
GGML_API void ggml_opt_init(
|
1239 |
+
struct ggml_context * ctx,
|
1240 |
+
struct ggml_opt_context * opt,
|
1241 |
+
struct ggml_opt_params params,
|
1242 |
+
int64_t nx);
|
1243 |
+
|
1244 |
+
// continue optimizing the function defined by the tensor f
|
1245 |
+
GGML_API enum ggml_opt_result ggml_opt_resume(
|
1246 |
+
struct ggml_context * ctx,
|
1247 |
+
struct ggml_opt_context * opt,
|
1248 |
+
struct ggml_tensor * f);
|
1249 |
+
|
1250 |
+
// continue optimizing the function defined by the tensor f
|
1251 |
+
GGML_API enum ggml_opt_result ggml_opt_resume_g(
|
1252 |
+
struct ggml_context * ctx,
|
1253 |
+
struct ggml_opt_context * opt,
|
1254 |
+
struct ggml_tensor * f,
|
1255 |
+
struct ggml_cgraph * gf,
|
1256 |
+
struct ggml_cgraph * gb);
|
1257 |
+
|
1258 |
+
//
|
1259 |
+
// quantization
|
1260 |
+
//
|
1261 |
+
|
1262 |
+
GGML_API size_t ggml_quantize_q4_0(const float * src, void * dst, int n, int k, int64_t * hist);
|
1263 |
+
GGML_API size_t ggml_quantize_q4_1(const float * src, void * dst, int n, int k, int64_t * hist);
|
1264 |
+
GGML_API size_t ggml_quantize_q5_0(const float * src, void * dst, int n, int k, int64_t * hist);
|
1265 |
+
GGML_API size_t ggml_quantize_q5_1(const float * src, void * dst, int n, int k, int64_t * hist);
|
1266 |
+
GGML_API size_t ggml_quantize_q8_0(const float * src, void * dst, int n, int k, int64_t * hist);
|
1267 |
+
|
1268 |
+
GGML_API size_t ggml_quantize_chunk(enum ggml_type type, const float * src, void * dst, int start, int n, int64_t * hist);
|
1269 |
+
|
1270 |
+
//
|
1271 |
+
// system info
|
1272 |
+
//
|
1273 |
+
|
1274 |
+
GGML_API int ggml_cpu_has_avx (void);
|
1275 |
+
GGML_API int ggml_cpu_has_avx2 (void);
|
1276 |
+
GGML_API int ggml_cpu_has_avx512 (void);
|
1277 |
+
GGML_API int ggml_cpu_has_avx512_vbmi(void);
|
1278 |
+
GGML_API int ggml_cpu_has_avx512_vnni(void);
|
1279 |
+
GGML_API int ggml_cpu_has_fma (void);
|
1280 |
+
GGML_API int ggml_cpu_has_neon (void);
|
1281 |
+
GGML_API int ggml_cpu_has_arm_fma (void);
|
1282 |
+
GGML_API int ggml_cpu_has_f16c (void);
|
1283 |
+
GGML_API int ggml_cpu_has_fp16_va (void);
|
1284 |
+
GGML_API int ggml_cpu_has_wasm_simd (void);
|
1285 |
+
GGML_API int ggml_cpu_has_blas (void);
|
1286 |
+
GGML_API int ggml_cpu_has_cublas (void);
|
1287 |
+
GGML_API int ggml_cpu_has_clblast (void);
|
1288 |
+
GGML_API int ggml_cpu_has_gpublas (void);
|
1289 |
+
GGML_API int ggml_cpu_has_sse3 (void);
|
1290 |
+
GGML_API int ggml_cpu_has_vsx (void);
|
1291 |
+
|
1292 |
+
//
|
1293 |
+
// Internal types and functions exposed for tests and benchmarks
|
1294 |
+
//
|
1295 |
+
|
1296 |
+
#ifdef __cplusplus
|
1297 |
+
// restrict not standard in C++
|
1298 |
+
#define GGML_RESTRICT
|
1299 |
+
#else
|
1300 |
+
#define GGML_RESTRICT restrict
|
1301 |
+
#endif
|
1302 |
+
typedef void (*dequantize_row_q_t)(const void * GGML_RESTRICT x, float * GGML_RESTRICT y, int k);
|
1303 |
+
typedef void (*quantize_row_q_t) (const float * GGML_RESTRICT x, void * GGML_RESTRICT y, int k);
|
1304 |
+
typedef void (*vec_dot_q_t) (const int n, float * GGML_RESTRICT s, const void * GGML_RESTRICT x, const void * GGML_RESTRICT y);
|
1305 |
+
|
1306 |
+
typedef struct {
|
1307 |
+
dequantize_row_q_t dequantize_row_q;
|
1308 |
+
quantize_row_q_t quantize_row_q;
|
1309 |
+
quantize_row_q_t quantize_row_q_reference;
|
1310 |
+
quantize_row_q_t quantize_row_q_dot;
|
1311 |
+
vec_dot_q_t vec_dot_q;
|
1312 |
+
enum ggml_type vec_dot_type;
|
1313 |
+
} quantize_fns_t;
|
1314 |
+
|
1315 |
+
quantize_fns_t ggml_internal_get_quantize_fn(size_t i);
|
1316 |
+
|
1317 |
+
#ifdef __cplusplus
|
1318 |
+
}
|
1319 |
+
#endif
|