From aaddcc0cbd10c9e7de46c6ad1ad6c4a20a9eaf17 Mon Sep 17 00:00:00 2001 From: niansa Date: Thu, 30 Mar 2023 07:03:33 -0500 Subject: [PATCH] Initial commit --- .gitignore | 74 ++ .gitmodules | 3 + CMakeLists.txt | 24 + gpt2/VERSION | 1 + gpt2/arith.c | 301 +++++++ gpt2/arith.h | 73 ++ gpt2/cp_utils.c | 316 +++++++ gpt2/cp_utils.h | 48 + gpt2/cutils.h | 152 ++++ gpt2/gpt2tc.c | 2023 +++++++++++++++++++++++++++++++++++++++++++ gpt2/gpt2tc.h | 143 +++ gpt2/gpt2vocab.txt | Bin 0 -> 371149 bytes gpt2/libnc.h | 426 +++++++++ gpt2/list.h | 96 ++ gpt2/readme.txt | 86 ++ justlm.hpp | 54 ++ libjustlm_core.cpp | 9 + libjustlm_gpt2.cpp | 80 ++ libjustlm_llama.cpp | 115 +++ llama.cpp | 1 + test.cpp | 12 + 21 files changed, 4037 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 CMakeLists.txt create mode 100644 gpt2/VERSION create mode 100644 gpt2/arith.c create mode 100644 gpt2/arith.h create mode 100644 gpt2/cp_utils.c create mode 100644 gpt2/cp_utils.h create mode 100644 gpt2/cutils.h create mode 100644 gpt2/gpt2tc.c create mode 100644 gpt2/gpt2tc.h create mode 100644 gpt2/gpt2vocab.txt create mode 100644 gpt2/libnc.h create mode 100644 gpt2/list.h create mode 100644 gpt2/readme.txt create mode 100644 justlm.hpp create mode 100644 libjustlm_core.cpp create mode 100644 libjustlm_gpt2.cpp create mode 100644 libjustlm_llama.cpp create mode 160000 llama.cpp create mode 100644 test.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4a0b530 --- /dev/null +++ b/.gitignore @@ -0,0 +1,74 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* +CMakeLists.txt.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..0477fdd --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "llama.cpp"] + path = llama.cpp + url = https://github.com/ggerganov/llama.cpp.git diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..858d069 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 3.14) + +project(libjustlm LANGUAGES C CXX) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +add_library(libjustlm STATIC + libjustlm_core.cpp + justlm.hpp +) + +set(LM_BACKEND "llama.cpp" CACHE STRING "The language model backend to use") + +if (LM_BACKEND STREQUAL "libnc gpt2") + add_library(libjustlm_gpt2 STATIC libjustlm_gpt2.cpp gpt2/arith.c gpt2/cp_utils.c gpt2/gpt2tc.c) + target_link_libraries(libjustlm_gpt2 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/gpt2/libnc.so pthread) +elseif (LM_BACKEND STREQUAL "llama.cpp") + add_subdirectory(llama.cpp) + add_library(libjustlm_llama STATIC libjustlm_llama.cpp) + target_link_libraries(libjustlm_llama PRIVATE llama) +else() + message(FATAL_ERROR "LM_BACKEND '${LM_BACKEND}' is unsupported. Please use either 'libnc gpt2' or 'llama.cpp'.") +endif() diff --git a/gpt2/VERSION b/gpt2/VERSION new file mode 100644 index 0000000..da4ce28 --- /dev/null +++ b/gpt2/VERSION @@ -0,0 +1 @@ +2021-04-24 diff --git a/gpt2/arith.c b/gpt2/arith.c new file mode 100644 index 0000000..79d0148 --- /dev/null +++ b/gpt2/arith.c @@ -0,0 +1,301 @@ +/* + * Arithmetic coder + * + * Copyright (c) 2018-2021 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cutils.h" +#include "arith.h" + +#define RANGE_MIN_BITS 16 +#define RANGE_MIN ((0xff << (RANGE_MIN_BITS - 8)) + 1) +#define RANGE_MAX (0xff << RANGE_MIN_BITS) + +//#define DUMP_PUT_BIT +//#define DUMP_GET_BIT + +void put_bit_init(PutBitState *s, uint8_t *buf, int buf_size, + PutBitWriteFunc *write_func, void *opaque) +{ + s->low = 0; + s->range = RANGE_MAX; + s->current_byte = 0xff; + s->n_bytes = 0; + s->buf = buf; + s->buf_size = buf_size; + s->idx = 0; + s->write_func = write_func; + s->opaque = opaque; + s->byte_count = 0; + assert(PROB_UNIT <= RANGE_MIN); +} + +static void put_byte(PutBitState *s, int v) +{ + s->buf[s->idx++] = v; + if (unlikely(s->idx == s->buf_size)) { + s->byte_count += s->idx; + s->write_func(s->opaque, s->buf, s->idx); + s->idx = 0; + } +} + +/* 0 <= v <= 0x1fe. The current output stream contains n_bytes with: + current_byte, then (n_bytes - 1) x 0xff + */ +static void put_val(PutBitState *s, int v) +{ + uint32_t carry, b; + +#ifdef DUMP_PUT_BIT + printf(" out=%d\n", v); +#endif + if (v == 0xff) { + s->n_bytes++; + } else { + if (s->n_bytes > 0) { + carry = v >> 8; + put_byte(s, s->current_byte + carry); + b = (0xff + carry) & 0xff; + while (s->n_bytes > 1) { + put_byte(s, b); + s->n_bytes--; + } + } + s->n_bytes = 1; + s->current_byte = v; + } +} + +static void put_val_flush(PutBitState *s) +{ + if (s->n_bytes > 0) { + put_val(s, 0); + } +} + +static void put_bit_renorm(PutBitState *s) +{ + uint32_t v; + /* after renormalisation: + 0 <= low <= RANGE_MAX + RANGE_MIN <= range <= RANGE_MAX + In the worst case before normalisation: + low_max = 2 * RANGE_MAX hence v <= 0x1fe + */ + while (s->range < RANGE_MIN) { + v = s->low >> RANGE_MIN_BITS; + put_val(s, v); + s->low = (s->low & ((1 << RANGE_MIN_BITS) - 1)) << 8; + s->range <<= 8; + } +} + +/* 0 < prob0 < PROB_UNIT */ +void put_bit(PutBitState *s, int prob0, int bit) +{ + int range0; + + assert(s->range >= RANGE_MIN); + range0 = ((uint64_t)s->range * prob0) >> PROB_UNIT_BITS; + assert(range0 > 0); + assert(range0 < s->range); +#if defined(DUMP_PUT_BIT) + { + static int count; + printf("%d: range=%d b=%d range0=%d low=%d\n", + count++, s->range, bit, range0, s->low); + } +#endif + if (!bit) { + s->range = range0; + } else { + s->low += range0; + s->range -= range0; + } + + put_bit_renorm(s); +} + +void put_bit_raw(PutBitState *s, int bit) +{ + int range0; + + assert(s->range >= RANGE_MIN); + range0 = s->range >> 1; + if (!bit) { + s->range = range0; + } else { + s->low += range0; + s->range -= range0; + } + + put_bit_renorm(s); +} + +/* return the minimum number of bits to be able to correctly decode */ +int64_t put_bit_flush(PutBitState *s) +{ + int n, val, mask; + + /* force larger range */ + if (s->range < (1 << RANGE_MIN_BITS)) { + put_val(s, s->low >> RANGE_MIN_BITS); + s->low = (s->low & ((1 << RANGE_MIN_BITS) - 1)) << 8; + s->range <<= 8; + } + + /* largest n such as 2^n <= range */ + n = 0; + while ((1 << (n + 1)) <= s->range) + n++; + assert(n >= RANGE_MIN_BITS && n <= (RANGE_MIN_BITS + 7)); + + val = s->low; + mask = (1 << n) - 1; + if ((val & mask) != 0) + val = (val + (1 << n)) & ~mask; + assert(val >= s->low && val < s->low + s->range); + + put_val(s, val >> RANGE_MIN_BITS); + put_val_flush(s); + if (s->idx > 0) { + s->byte_count += s->idx; + s->write_func(s->opaque, s->buf, s->idx); + s->idx = 0; + } + return (s->byte_count - 1) * 8 + (RANGE_MIN_BITS + 8 - n); +} + +/* return the approximate number of written bits */ +int64_t put_bit_get_bit_count(PutBitState *s) +{ + int n; + n = 0; + while ((1 << (n + 1)) <= s->range) + n++; + return (s->byte_count + s->idx) * 8 + (RANGE_MIN_BITS + 7 - n); +} + +/****************************************/ + +static void refill(GetBitState *s) +{ + s->range <<= 8; + s->low <<= 8; + if (s->idx >= s->buf_len) { + if (!s->read_func) + return; /* pad with zeros */ + s->buf_len = s->read_func(s->opaque, s->buf, s->buf_size); + s->byte_count += s->buf_len; + s->idx = 0; + } +#ifdef DUMP_GET_BIT + printf(" in=%d\n", s->buf[s->idx]); +#endif + s->low += s->buf[s->idx++]; +} + +void get_bit_init(GetBitState *s, uint8_t *buf, size_t buf_size, + GetBitReadFunc *read_func, void *opaque) +{ + int i; + s->buf_size = buf_size; + s->buf = buf; + s->read_func = read_func; + s->opaque = opaque; + if (read_func) { + s->buf_len = 0; + } else { + /* prefilled buffer */ + s->buf_len = s->buf_size; + } + s->byte_count = s->buf_len; + s->range = 0; + s->low = 0; + s->idx = 0; + for(i = 0; i <= RANGE_MIN_BITS; i += 8) { + refill(s); + } + s->range = RANGE_MAX; +} + +/* 0 < prob0 < PROB_UNIT */ +int get_bit(GetBitState *s, int prob0) +{ + int b, range0; + + assert(s->range >= RANGE_MIN); + range0 = ((uint64_t)s->range * prob0) >> PROB_UNIT_BITS; + assert(range0 > 0); + assert(range0 < s->range); + b = s->low >= range0; +#ifdef DUMP_GET_BIT + { + static int count; + printf("%d: range=%d b=%d range0=%d low=%d\n", count++, s->range, b, range0, s->low); + } +#endif + if (b) { + s->low -= range0; + s->range -= range0; + } else { + s->range = range0; + } + while (s->range < RANGE_MIN) + refill(s); + return b; +} + +/* no context */ +int get_bit_raw(GetBitState *s) +{ + int b, range0; + range0 = s->range >> 1; + b = s->low >= range0; + if (b) { + s->low -= range0; + s->range -= range0; + } else { + s->range = range0; + } + if (s->range < RANGE_MIN) + refill(s); + return b; +} + +/* return the approximate number of read bits */ +int64_t get_bit_get_bit_count(GetBitState *s) +{ + int n; + n = 0; + while ((1 << (n + 1)) <= s->range) + n++; + return (s->byte_count - s->buf_len + s->idx) * 8 - n; +} diff --git a/gpt2/arith.h b/gpt2/arith.h new file mode 100644 index 0000000..d1a4e31 --- /dev/null +++ b/gpt2/arith.h @@ -0,0 +1,73 @@ +/* + * Arithmetic coder + * + * Copyright (c) 2018-2019 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef ARITH_H +#define ARITH_H + +#define PROB_UNIT_BITS 15 +#define PROB_UNIT (1 << PROB_UNIT_BITS) + +typedef void PutBitWriteFunc(void *opaque, const uint8_t *buf, size_t buf_size); + +typedef struct { + uint32_t range; + uint32_t low; + uint8_t current_byte; + uint32_t n_bytes; + uint8_t *buf; + size_t buf_size; + size_t idx; /* current position in bytes */ + PutBitWriteFunc *write_func; + void *opaque; + uint64_t byte_count; +} PutBitState; + +void put_bit_init(PutBitState *s, uint8_t *buf, int buf_size, + PutBitWriteFunc *write_func, void *opaque); +void put_bit(PutBitState *s, int prob0, int bit); +void put_bit_raw(PutBitState *s, int bit); +int64_t put_bit_flush(PutBitState *s); +int64_t put_bit_get_bit_count(PutBitState *s); + +/* return the number of read bytes */ +typedef ssize_t GetBitReadFunc(void *opaque, uint8_t *buf, size_t buf_size); + +typedef struct { + uint8_t *buf; + int buf_len; + int buf_size; + int idx; + uint32_t low; + uint32_t range; + GetBitReadFunc *read_func; + void *opaque; + uint64_t byte_count; +} GetBitState; + +void get_bit_init(GetBitState *s, uint8_t *buf, size_t buf_size, + GetBitReadFunc *read_func, void *opaque); +int get_bit(GetBitState *s, int prob0); +int get_bit_raw(GetBitState *s); +int64_t get_bit_get_bit_count(GetBitState *s); + +#endif /* ARITH_H */ diff --git a/gpt2/cp_utils.c b/gpt2/cp_utils.c new file mode 100644 index 0000000..d049d92 --- /dev/null +++ b/gpt2/cp_utils.c @@ -0,0 +1,316 @@ +/* + * Compression utilities + * + * Copyright (c) 2018-2019 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef _WIN32 +#include +#endif + +#include "cutils.h" +#include "libnc.h" +#include "cp_utils.h" + +void fatal_error(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + fprintf(stderr, "Fatal error: "); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + exit(1); +} + +int64_t get_time_ms(void) +{ +#ifdef _WIN32 + struct timeval tv; + gettimeofday(&tv, NULL); + return (int64_t)tv.tv_sec * 1000 + (tv.tv_usec / 1000U); +#else + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (int64_t)ts.tv_sec * 1000 + (ts.tv_nsec / 1000000U); +#endif +} + +void fput_u8(FILE *f, uint8_t v) +{ + fputc(v, f); +} + +int fget_u8(FILE *f, uint8_t *pv) +{ + int c; + c = fgetc(f); + if (c < 0) + return -1; + *pv = c; + return 0; +} + +void fput_be16(FILE *f, uint16_t v) +{ + fputc(v >> 8, f); + fputc(v >> 0, f); +} + +int fget_be16(FILE *f, uint16_t *pv) +{ + uint8_t buf[2]; + if (fread(buf, 1, sizeof(buf), f) != sizeof(buf)) + return -1; + *pv = (buf[0] << 8) | + (buf[1] << 0); + return 0; +} + +void fput_be32(FILE *f, uint32_t v) +{ + fputc(v >> 24, f); + fputc(v >> 16, f); + fputc(v >> 8, f); + fputc(v >> 0, f); +} + +int fget_be32(FILE *f, uint32_t *pv) +{ + uint8_t buf[4]; + if (fread(buf, 1, sizeof(buf), f) != sizeof(buf)) + return -1; + *pv = (buf[0] << 24) | + (buf[1] << 16) | + (buf[2] << 8) | + (buf[3] << 0); + return 0; +} + +void fput_sgd_opt(FILE *f, const SGDOptParams *p) +{ + fput_u8(f, p->algo); + switch(p->algo) { + case SGD_OPT_BASIC: + break; + case SGD_OPT_ADAM: + fput_f32(f, p->u.adam.beta1); + fput_f32(f, p->u.adam.beta2); + fput_f32(f, p->u.adam.eps); + fput_f32(f, p->u.adam.gradient_clip); + break; + default: + abort(); + } +} + +int fget_sgd_opt(FILE *f, SGDOptParams *p) +{ + uint8_t v8; + + if (fget_u8(f, &v8)) + return -1; + p->algo = v8; + switch(p->algo) { + case SGD_OPT_BASIC: + break; + case SGD_OPT_ADAM: + if (fget_f32(f, &p->u.adam.beta1)) + return -1; + if (fget_f32(f, &p->u.adam.beta2)) + return -1; + if (fget_f32(f, &p->u.adam.eps)) + return -1; + if (fget_f32(f, &p->u.adam.gradient_clip)) + return -1; + break; + default: + return -1; + } + return 0; +} + +void dump_sgd_opt_params(FILE *f, const SGDOptParams *p) +{ + switch(p->algo) { + case SGD_OPT_BASIC: + fprintf(f, " sgd_opt=%s", + "none"); + break; + case SGD_OPT_ADAM: + fprintf(f, " sgd_opt=%s beta1=%g beta2=%g eps=%g gclip=%g", + "adam", + p->u.adam.beta1, + p->u.adam.beta2, + p->u.adam.eps, + p->u.adam.gradient_clip); + break; + default: + abort(); + } +} + +typedef union { + float f; + uint32_t u32; +} f32; + +void fput_f32(FILE *f, float v) +{ + f32 u; + u.f = v; + fput_be32(f, u.u32); +} + +int fget_f32(FILE *f, float *pv) +{ + f32 u; + if (fget_be32(f, &u.u32)) + return -1; + *pv = u.f; + return 0; +} + +void write_sym(PutBitState *pb, const float *prob_table, int n_symb, int sym) +{ + int start, range, prob0, bit, range0; + float p, p0; + + start = 0; + range = n_symb; + p = 1.0; /* invariant: p=sum(prob_table[start...start + range]) */ + while (range > 1) { + range0 = range >> 1; + p0 = vec_sum_f32(prob_table + start, range0); + prob0 = lrintf(p0 * PROB_UNIT / p); + prob0 = clamp_int(prob0, 1, PROB_UNIT - 1); + bit = sym >= (start + range0); + put_bit(pb, prob0, bit); + if (bit) { + start += range0; + range = range - range0; + p = p - p0; + } else { + p = p0; + range = range0; + } + } +} + +int read_sym(GetBitState *gb, const float *prob_table, int n_symb) +{ + int start, range, prob0, bit, range0; + float p, p0; + + start = 0; + range = n_symb; + p = 1.0; /* invariant: p=sum(prob_table[start...start + range]) */ + while (range > 1) { + range0 = range >> 1; + p0 = vec_sum_f32(prob_table + start, range0); + prob0 = lrintf(p0 * PROB_UNIT / p); + prob0 = clamp_int(prob0, 1, PROB_UNIT - 1); + bit = get_bit(gb, prob0); + if (bit) { + start += range0; + range = range - range0; + p = p - p0; + } else { + p = p0; + range = range0; + } + } + return start; +} + +void create_debug_dir(char *debug_dir, size_t debug_dir_size, + const char *debug_path, const char *prefix) +{ + char name1[1024]; + struct tm *tm; + time_t ti; + + snprintf(name1, sizeof(name1), "%s/%s", debug_path, prefix); +#ifdef _WIN32 + _mkdir(name1); +#else + mkdir(name1, 0777); +#endif + + ti = time(NULL); + tm = localtime(&ti); + snprintf(debug_dir, debug_dir_size, "%s/%04u%02u%02u-%02u%02u%02u", + name1, + tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec); +#ifdef _WIN32 + _mkdir(debug_dir); +#else + mkdir(debug_dir, 0777); +#endif +} + +/* we print at least 3 significant digits with at most 5 chars, except + if larger than 9999T. The value is rounded to zero. */ +char *get_si_prefix(char *buf, int buf_size, uint64_t val) +{ + static const char suffixes[4] = "kMGT"; + uint64_t base; + int i; + + if (val <= 999) { + snprintf(buf, buf_size, "%" PRId64, val); + } else { + base = 1000; + for(i=0;i<4;i++) { + /* Note: we round to 0 */ + if (val < base * 10) { + snprintf(buf, buf_size, "%0.2f%c", + floor((val * 100.0) / base) / 100.0, + suffixes[i]); + break; + } else if (val < base * 100) { + snprintf(buf, buf_size, "%0.1f%c", + floor((val * 10.0) / base) / 10.0, + suffixes[i]); + break; + } else if (val < base * 1000 || (i == 3)) { + snprintf(buf, buf_size, + "%" PRId64 "%c", + val / base, + suffixes[i]); + break; + } + base = base * 1000; + } + } + return buf; +} diff --git a/gpt2/cp_utils.h b/gpt2/cp_utils.h new file mode 100644 index 0000000..74deaa0 --- /dev/null +++ b/gpt2/cp_utils.h @@ -0,0 +1,48 @@ +/* + * Compression utilities + * + * Copyright (c) 2018-2019 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "arith.h" +#include "libnc.h" + +void __attribute__((noreturn, format(printf, 1, 2))) fatal_error(const char *fmt, ...); + +int64_t get_time_ms(void); +void fput_u8(FILE *f, uint8_t v); +int fget_u8(FILE *f, uint8_t *pv); +void fput_be16(FILE *f, uint16_t v); +int fget_be16(FILE *f, uint16_t *pv); +void fput_be32(FILE *f, uint32_t v); +int fget_be32(FILE *f, uint32_t *pv); +void fput_f32(FILE *f, float v); +int fget_f32(FILE *f, float *pv); +void fput_sgd_opt(FILE *f, const SGDOptParams *p); +int fget_sgd_opt(FILE *f, SGDOptParams *p); +void dump_sgd_opt_params(FILE *f, const SGDOptParams *p); + +void write_sym(PutBitState *pb, const float *prob_table, int n_symb, int sym); +int read_sym(GetBitState *gb, const float *prob_table, int n_symb); + +void create_debug_dir(char *debug_dir, size_t debug_dir_size, + const char *debug_path, const char *prefix); +char *get_si_prefix(char *buf, int buf_size, uint64_t val); + diff --git a/gpt2/cutils.h b/gpt2/cutils.h new file mode 100644 index 0000000..68c1df2 --- /dev/null +++ b/gpt2/cutils.h @@ -0,0 +1,152 @@ +#ifndef CUTILS_H +#define CUTILS_H + +#include + +#define force_inline inline __attribute__((always_inline)) +#define no_inline __attribute__((noinline)) +#define __unused __attribute__((unused)) +#define xglue(x, y) x ## y +#define glue(x, y) xglue(x, y) +#ifndef offsetof +#define offsetof(type, field) ((size_t) &((type *)0)->field) +#endif +#define countof(x) (sizeof(x) / sizeof(x[0])) +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) + +typedef int BOOL; + +#ifndef FALSE +enum { + FALSE = 0, + TRUE = 1, +}; +#endif + +typedef struct { + uint16_t u16; +} bfloat16_t; + +#if defined(__x86_64__) +static inline int64_t get_cycles(void) +{ + uint32_t low,high; + int64_t val; + asm volatile("rdtsc" : "=a" (low), "=d" (high)); + val = high; + val <<= 32; + val |= low; + return val; +} +#else +static inline int64_t get_cycles(void) +{ + int64_t val; + asm volatile ("rdtsc" : "=A" (val)); + return val; +} +#endif + +static inline int max_int(int a, int b) +{ + if (a > b) + return a; + else + return b; +} + +static inline int min_int(int a, int b) +{ + if (a < b) + return a; + else + return b; +} + +static inline size_t max_size_t(size_t a, size_t b) +{ + if (a > b) + return a; + else + return b; +} + +static inline size_t min_size_t(size_t a, size_t b) +{ + if (a < b) + return a; + else + return b; +} + +static inline ssize_t max_ssize_t(ssize_t a, ssize_t b) +{ + if (a > b) + return a; + else + return b; +} + +static inline ssize_t min_ssize_t(ssize_t a, ssize_t b) +{ + if (a < b) + return a; + else + return b; +} + +static inline int clamp_int(int val, int min_val, int max_val) +{ + if (val < min_val) + return min_val; + else if (val > max_val) + return max_val; + else + return val; +} + +static inline float clamp_float(float val, float min_val, float max_val) +{ + if (val < min_val) + return min_val; + else if (val > max_val) + return max_val; + else + return val; +} + +/* WARNING: undefined if a = 0 */ +static inline int clz32(unsigned int a) +{ + return __builtin_clz(a); +} + +/* WARNING: undefined if a = 0 */ +static inline int clz64(uint64_t a) +{ + return __builtin_clzll(a); +} + +static inline int floor_log2(uint64_t a) +{ + return 63 - clz64(a); +} + +static inline int ceil_log2(uint64_t a) +{ + if (a <= 1) + return 0; + else + return 64 - clz64(a - 1); +} + +static inline float squaref(float x) +{ + return x * x; +} + +#define DUP8(a) a, a, a, a, a, a, a, a + +#endif /* CUTILS_H */ + diff --git a/gpt2/gpt2tc.c b/gpt2/gpt2tc.c new file mode 100644 index 0000000..3ffd4ae --- /dev/null +++ b/gpt2/gpt2tc.c @@ -0,0 +1,2023 @@ +/* + * Text Completion with GPT-2 Transformer + * + * Copyright (c) 2019-2021 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cutils.h" +#include "arith.h" +#include "libnc.h" +#include "cp_utils.h" +#include "list.h" +#include "gpt2tc.h" + + +/************************************************/ +/* Transformer model */ + +static int nb_threads = 1; + +/* [seg_len, d_model] -> + [n_head, seg_len, d_model/n_head] */ +static NCTensor *split_head(NCTensor *x, int n_head) +{ + const size_t *dims; + int n_dims, axis[3]; + + dims = nc_tensor_get_dims(x, &n_dims); + assert(n_dims == 2); + assert((dims[0] % n_head) == 0); + x = nc_reshape_3d(x, dims[0] / n_head, n_head, dims[1]); + /* [seg_len, n_head, d_model/n_head] */ + axis[0] = 0; + axis[1] = 2; + axis[2] = 1; + return nc_permute(x, 3, axis); +} + +/* [n_head, seg_len, d_value] + -> [seg_len, d_value * n_head] */ +static NCTensor *concat_head(NCTensor *x) +{ + const size_t *dims; + int n_dims, axis[3]; + + axis[0] = 0; + axis[1] = 2; + axis[2] = 1; + x = nc_permute(x, 3, axis); + dims = nc_tensor_get_dims(x, &n_dims); + assert(n_dims == 3); + /* [seg_len, n_head, d_value] */ + return nc_reshape_2d(x, dims[0] * dims[1], dims[2]); +} + +#define MAT_STRIDE 64 + +/* convert the matrix to strided representation */ +static void convert_mat(NCTensor **pw) +{ + NCTensor *w; + int m, n, n_dims, r; + const size_t *dims; + int axis[3]; + + w = *pw; + dims = nc_tensor_get_dims(w, &n_dims); + assert(n_dims == 2); + m = dims[0]; + n = dims[1]; + r = (-m) % MAT_STRIDE; + if (r < 0) + r += MAT_STRIDE; + w = nc_pad(w, 0, NC_PAD_ZERO, r, NC_PAD_ZERO); + w = nc_reshape_3d(w, MAT_STRIDE, (m + MAT_STRIDE - 1) / MAT_STRIDE, n); + axis[0] = 0; + axis[1] = 2; + axis[2] = 1; + w = nc_permute(w, 3, axis); + *pw = w; +} + +static TransformerModel *trf_init(const TransformerModelParams *p, + const char *coefs_filename) +{ + TransformerModel *s; + NCContext *m; + NCDevice *d; + int layer_idx; + TransformerLayer *layers, *tl; + + s = nc_mallocz(sizeof(*s)); + rnd_init(&s->rnd_state, p->seed); + s->n_layer = p->n_layer; + s->d_model = p->d_model; + s->n_head = p->n_head; + s->d_key = p->d_key; + s->d_value = p->d_value; + s->d_inner = p->d_inner; + s->n_ctx = p->n_ctx; + s->n_symbols = p->n_symbols; + + m = nc_context_init(nb_threads); + s->model = m; + d = nc_new_cpu_device(m); + s->device = d; + + nc_param_list_init(&s->param_list); + /* disable graph for the parameters */ + nc_param_list_set_graph(&s->param_list, FALSE); + + layers = nc_mallocz(sizeof(layers[0]) * s->n_layer); + s->layers = layers; + for(layer_idx = 0; layer_idx < s->n_layer; layer_idx++) { + tl = &layers[layer_idx]; + tl->ln_1_g = nc_new_tensor_1d(d, NC_TYPE_F32, s->d_model); + nc_new_param(&s->param_list, &tl->ln_1_g, "h%d/ln_1/g", layer_idx); + + tl->ln_1_b = nc_new_tensor_1d(d, NC_TYPE_F32, s->d_model); + nc_new_param(&s->param_list, &tl->ln_1_b, "h%d/ln_1/b", layer_idx); + + tl->attn_w = nc_new_tensor_2d(d, NC_TYPE_F16, s->n_head * s->d_key * 3, + s->d_model); + nc_new_param(&s->param_list, &tl->attn_w, + "h%d/attn/c_attn/w", layer_idx); + + tl->attn_b = nc_new_tensor_1d(d, NC_TYPE_F32, s->n_head * s->d_key * 3); + nc_new_param(&s->param_list, &tl->attn_b, + "h%d/attn/c_attn/b", layer_idx); + + tl->attn_proj_w = nc_new_tensor_2d(d, NC_TYPE_F16, s->d_model, + s->n_head * s->d_value); + nc_new_param(&s->param_list, &tl->attn_proj_w, + "h%d/attn/c_proj/w", layer_idx); + + tl->attn_proj_b = nc_new_tensor_1d(d, NC_TYPE_F32, s->d_model); + nc_new_param(&s->param_list, &tl->attn_proj_b, + "h%d/attn/c_proj/b", layer_idx); + + tl->ln_2_g = nc_new_tensor_1d(d, NC_TYPE_F32, s->d_model); + nc_new_param(&s->param_list, &tl->ln_2_g, "h%d/ln_2/g", layer_idx); + + tl->ln_2_b = nc_new_tensor_1d(d, NC_TYPE_F32, s->d_model); + nc_new_param(&s->param_list, &tl->ln_2_b, "h%d/ln_2/b", layer_idx); + + tl->mlp_fc_w = nc_new_tensor_2d(d, NC_TYPE_F16, s->d_inner, + s->d_model); + nc_new_param(&s->param_list, &tl->mlp_fc_w, + "h%d/mlp/c_fc/w", layer_idx); + + tl->mlp_fc_b = nc_new_tensor_1d(d, NC_TYPE_F32, s->d_inner); + nc_new_param(&s->param_list, &tl->mlp_fc_b, + "h%d/mlp/c_fc/b", layer_idx); + + tl->mlp_proj_w = nc_new_tensor_2d(d, NC_TYPE_F16, s->d_model, + s->d_inner); + nc_new_param(&s->param_list, &tl->mlp_proj_w, + "h%d/mlp/c_proj/w", layer_idx); + + tl->mlp_proj_b = nc_new_tensor_1d(d, NC_TYPE_F32, s->d_model); + nc_new_param(&s->param_list, &tl->mlp_proj_b, + "h%d/mlp/c_proj/b", layer_idx); + } + + s->ln_f_g = nc_new_tensor_1d(d, NC_TYPE_F32, s->d_model); + nc_new_param(&s->param_list, &s->ln_f_g, "ln_f/g"); + + s->ln_f_b = nc_new_tensor_1d(d, NC_TYPE_F32, s->d_model); + nc_new_param(&s->param_list, &s->ln_f_b, "ln_f/b"); + + s->wte = nc_new_tensor_2d(d, NC_TYPE_F16, s->d_model, + s->n_symbols); + nc_new_param(&s->param_list, &s->wte, "wte"); + + s->wpe = nc_new_tensor_2d(d, NC_TYPE_F32, s->d_model, + s->n_ctx); + nc_new_param(&s->param_list, &s->wpe, "wpe"); + + nc_load_coefs(&s->param_list, coefs_filename); + + /* optimize the variable storage */ + s->wte_trans = nc_transpose(nc_dup_tensor(s->wte)); + + convert_mat(&s->wte_trans); + + for(layer_idx = 0; layer_idx < s->n_layer; layer_idx++) { + tl = &layers[layer_idx]; + convert_mat(&tl->attn_w); + convert_mat(&tl->attn_proj_w); + convert_mat(&tl->mlp_fc_w); + convert_mat(&tl->mlp_proj_w); + } + return s; +} + +typedef struct { + int mem_len; + NCTensor **mem_k; + NCTensor **mem_v; +} BatchEntry; + +/* dimensions: output[train_len * n_streams][n_symbols], + input[train_len * n_streams], tab_mem[n_streams], mem_k[n_layer] + mem_v[n_layer]. */ +static NCTensor *trf_eval(TransformerModel *s, int train_len, + int n_streams, BatchEntry *tab_mem, + NCTensor *input) +{ + NCTensor *layer_input, **tab_tmp, *output, *position; + TransformerLayer *tl; + int layer_idx, i, j, *ptr; + BatchEntry *be; + + tab_tmp = nc_mallocz(sizeof(tab_tmp[0]) * + max_int(max_int(3, train_len), + max_int(s->n_head, s->n_layer))); + + position = nc_new_tensor_1d(s->device, NC_TYPE_I32, + train_len * n_streams); + ptr = nc_tensor_get_ptr(position, NULL); + for(i = 0; i < train_len; i++) { + for(j = 0; j < n_streams; j++) { + ptr[i * n_streams + j] = tab_mem[j].mem_len + i; + } + } + + layer_input = nc_get_col(nc_dup_tensor(s->wte), input); + layer_input = nc_convert(layer_input, NC_TYPE_F32); + layer_input = nc_add(layer_input, nc_get_col(nc_dup_tensor(s->wpe), + position)); + + for(layer_idx = 0; layer_idx < s->n_layer; layer_idx++) { + NCTensor *query, *key, *value, *ff_input, *t0, **tab_tmp2; + + tl = &s->layers[layer_idx]; + + t0 = nc_add(nc_mul(nc_layer_norm(nc_dup_tensor(layer_input), 1e-5), + nc_dup_tensor(tl->ln_1_g)), + nc_dup_tensor(tl->ln_1_b)); + + t0 = nc_add(nc_matmul_stride(nc_dup_tensor(tl->attn_w), t0), + nc_dup_tensor(tl->attn_b)); + tab_tmp2 = nc_mallocz(sizeof(tab_tmp2[0]) * n_streams); + + /* [ train_len * n_streams d_model * 3] -> + n_streams * [ train_len d_model * 3] */ + nc_hsplit(tab_tmp2, t0, n_streams, NULL); + for(i = 0; i < n_streams; i++) { + be = &tab_mem[i]; + + t0 = tab_tmp2[i]; + nc_vsplit(tab_tmp, t0, 3, NULL); + query = tab_tmp[0]; + key = tab_tmp[1]; + value = tab_tmp[2]; + + /* split query, key and value for each head */ + key = split_head(key, s->n_head); + query = split_head(query, s->n_head); + value = split_head(value, s->n_head); + + /* save the key and value to the memory */ + t0 = nc_slice_alias(be->mem_k[layer_idx], + 1, be->mem_len, be->mem_len + train_len); + nc_tensor_copy(t0, key); + nc_free_tensor(t0); + nc_free_tensor(key); + + t0 = nc_slice_alias(be->mem_v[layer_idx], + 1, be->mem_len, be->mem_len + train_len); + nc_tensor_copy(t0, value); + nc_free_tensor(t0); + nc_free_tensor(value); + + key = nc_slice_alias(be->mem_k[layer_idx], + 1, 0, be->mem_len + train_len); + value = nc_slice_alias(be->mem_v[layer_idx], + 1, 0, be->mem_len + train_len); + + /* cross product term */ + t0 = nc_matmul_add(key, query, NULL, + TRUE, FALSE); + t0 = nc_mul(t0, nc_new_f32(s->device, 1.0f / sqrtf(s->d_key))); + + /* set the future cross products to -infinity so that they + don't change the softmax result */ + t0 = nc_slt_mat_set(t0, be->mem_len + 1, -INFINITY); + + t0 = nc_soft_max(t0); + t0 = nc_matmul(value, t0); + + /* merge all the heads */ + tab_tmp2[i] = concat_head(t0); + } + + t0 = nc_hconcat(tab_tmp2, n_streams); + nc_free(tab_tmp2); + + /* projection */ + t0 = nc_add(nc_matmul_stride(nc_dup_tensor(tl->attn_proj_w), t0), + nc_dup_tensor(tl->attn_proj_b)); + + t0 = nc_add(t0, layer_input); + + ff_input = nc_dup_tensor(t0); + + t0 = nc_add(nc_mul(nc_layer_norm(t0, 1e-5), + nc_dup_tensor(tl->ln_2_g)), + nc_dup_tensor(tl->ln_2_b)); + + t0 = nc_add(nc_matmul_stride(nc_dup_tensor(tl->mlp_fc_w), t0), + nc_dup_tensor(tl->mlp_fc_b)); + t0 = nc_gelu(t0); + + t0 = nc_add(nc_matmul_stride(nc_dup_tensor(tl->mlp_proj_w), t0), + nc_dup_tensor(tl->mlp_proj_b)); + + layer_input = nc_add(t0, ff_input); + } + + { + NCTensor *t0; + t0 = nc_add(nc_mul(nc_layer_norm(layer_input, 1e-5), + nc_dup_tensor(s->ln_f_g)), + nc_dup_tensor(s->ln_f_b)); + + t0 = nc_matmul_stride(nc_dup_tensor(s->wte_trans), t0); + /* need to resize the output to the exact size because the + strided matrix is larger */ + output = nc_resize(t0, s->n_symbols); + } + nc_free(tab_tmp); + return output; +} + +static void trf_end(TransformerModel *s) +{ + nc_free_tensor(s->wte_trans); + + nc_param_list_end(&s->param_list); + nc_free(s->layers); + nc_context_end(s->model); + nc_free(s); +} + +static const char *gpt2_model_name[] = { "117M", "345M", "774M", "1558M" }; + +GPT2ModelEnum parse_model(const char *str) +{ + int i; + for(i = 0; i < countof(gpt2_model_name); i++) { + if (!strcmp(gpt2_model_name[i], str)) + return i; + } + return (GPT2ModelEnum)-1; +} + +void trf_set_params(TransformerModelParams *p, GPT2ModelEnum model) +{ + memset(p, 0, sizeof(*p)); + p->seed = 123; + switch(model) { + case GPT2_MODEL_117M: + p->n_layer = 12; + p->d_model = 768; + break; + case GPT2_MODEL_345M: + p->n_layer = 24; + p->d_model = 1024; + break; + case GPT2_MODEL_774M: + p->n_layer = 36; + p->d_model = 1280; + break; + case GPT2_MODEL_1558M: + p->n_layer = 48; + p->d_model = 1600; + break; + default: + abort(); + } + p->d_key = 64; + p->n_head = p->d_model / p->d_key; + p->d_value = p->d_key; + p->d_inner = p->d_model * 4; + p->n_ctx = 1024; + p->n_symbols = 50257; +} + +typedef uint16_t DataSymbol; + +/****************************************************************/ +/* preprocessor */ + +static uint32_t hash_calc(const uint8_t *buf, int len, int n_bits) +{ + uint32_t h; + int i; + + h = 1; + for(i = 0; i < len; i++) { + h = h * 263 + buf[i]; + } + return h & ((1 << n_bits) - 1); +} + +static void hash_resize(WordList *s, int hash_bits) +{ + int i, h; + Word *p; + + s->hash_bits = hash_bits; + s->hash_size = 1 << hash_bits; + free(s->hash_table); + s->hash_table = malloc(sizeof(s->hash_table[0]) * s->hash_size); + for(i = 0; i < s->hash_size; i++) + s->hash_table[i] = -1; + for(i = 0; i < s->word_count; i++) { + p = &s->words[i]; + h = hash_calc(p->buf, p->len, s->hash_bits); + p->next = s->hash_table[h]; + s->hash_table[h] = i; + } +} + +static WordList *word_list_init(void) +{ + WordList *s; + + s = malloc(sizeof(WordList)); + memset(s, 0, sizeof(*s)); + s->word_count = 0; + s->word_size = 0; + hash_resize(s, 12); + return s; +} + +static void word_list_end(WordList *s) +{ + int i; + Word *p; + + for(i = 0; i < s->word_count; i++) { + p = &s->words[i]; + free(p->buf); + } + free(s->words); + free(s->hash_table); + free(s); +} + +static int64_t hash_lookup_count; +static int64_t hash_it_count; + +/* the hash size contains HASH_SIZE_FACTOR times more entries */ +#define HASH_SIZE_FACTOR 2 + +static Word *word_find_add(WordList *s, const uint8_t *buf, int len, int add) +{ + uint32_t h, idx; + Word *p; + + h = hash_calc(buf, len, s->hash_bits); + idx = s->hash_table[h]; + hash_lookup_count++; + while (idx != -1) { + hash_it_count++; + p = &s->words[idx]; + if (p->len == len && !memcmp(p->buf, buf, len)) + return p; + idx = p->next; + } + + if (!add) + return NULL; + + if (s->word_count >= s->word_size) { + size_t new_size = s->word_size + s->word_size / 2; + if (new_size < 32) + new_size = 32; + if (s->word_count + 1 > new_size) + new_size = s->word_count + 1; + s->words = realloc(s->words, new_size * sizeof(s->words[0])); + s->word_size = new_size; + + } + /* resize the hash table when needed */ + if ((s->word_count * HASH_SIZE_FACTOR) > s->hash_size) { + int hash_bits = s->hash_bits; + while ((s->word_count * HASH_SIZE_FACTOR) > (1 << hash_bits)) + hash_bits++; + hash_resize(s, hash_bits); + + /* recompute the hash with the new hash table size */ + h = hash_calc(buf, len, s->hash_bits); + } + + idx = s->word_count++; + p = &s->words[idx]; + p->len = len; + p->buf = malloc(len + 1); + memcpy(p->buf, buf, len); + p->buf[len] = 0; + p->next = s->hash_table[h]; + s->hash_table[h] = idx; + return p; +} + +static void word_load(WordList *s, const char *filename) +{ + FILE *f; + uint8_t buf[1024]; + int len, c; + + f = fopen(filename, "rb"); + if (!f) { + perror(filename); + exit(1); + } + len = 0; + for(;;) { + c = fgetc(f); + if (c < 0) + break; + if (c == '\n') { + if (len > 0) { + word_find_add(s, buf, len, TRUE); + } + len = 0; + } else { + if (c == '\\') { + c = fgetc(f); + if (c < 0) + break; + if (c == 'n') { + c = '\n'; + } else if (c != '\\') { + fprintf(stderr, "Invalid escape\n"); + exit(1); + } + } + if (len >= sizeof(buf)) { + fprintf(stderr, "Word too long\n"); + exit(1); + } + buf[len++] = c; + } + } + fclose(f); +} + +typedef enum { + CAT_SPACE, + CAT_LETTER, + CAT_NUMBER, + CAT_OTHER, +} CharCatEnum; + +static int get_char_cat(int c) +{ + if (c == ' ') { + return CAT_SPACE; + } else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || + c >= 128) { + return CAT_LETTER; + } else if (c >= '0' && c <= '9') { + return CAT_NUMBER; + } else { + return CAT_OTHER; + } +} + +static BOOL match(size_t *pmatch_len, + const uint8_t *buf, size_t buf_len, const char *str) +{ + size_t len; + len = strlen(str); + if (len <= buf_len && !memcmp(buf, str, len)) { + *pmatch_len = len; + return TRUE; + } else { + *pmatch_len = 0; + return FALSE; + } +} + +static size_t gpt2_get_word(const uint8_t *buf, size_t buf_len) +{ + size_t len, p; + int cat; + + if (buf_len == 0) + return 0; + if (buf[0] == '\'' && + (match(&len, buf, buf_len, "'s") || + match(&len, buf, buf_len, "'t") || + match(&len, buf, buf_len, "'re") || + match(&len, buf, buf_len, "'ve") || + match(&len, buf, buf_len, "'m") || + match(&len, buf, buf_len, "'ll") || + match(&len, buf, buf_len, "'d"))) { + return len; + } + p = 0; + if (buf[0] == ' ' && buf_len >= 2) + p++; + if (buf[p] != ' ') { + cat = get_char_cat(buf[p]); + len = 1 + p; + while (len < buf_len && get_char_cat(buf[len]) == cat) + len++; + return len; + } else { + return 1; + } +} + +static __unused void print_word(const uint8_t *buf, size_t len) +{ + size_t i; + int c; + for(i = 0; i < len; i++) { + c = buf[i]; + if (c >= ' ' && c <= '~') + putchar(c); + else + printf("\\x%02x", c); + } +} + +void gpt2_pp_encode(const char *word_filename, + const char *in_filename, const char *out_filename) +{ + FILE *f, *fo; + size_t buf_size, buf_pos, word_len, len, i; + uint8_t *buf; + WordList *s; + Word *p; + + f = fopen(in_filename, "rb"); + if (!f) { + perror(in_filename); + exit(1); + } + + fseek(f, 0, SEEK_END); + buf_size = ftell(f); + fseek(f, 0, SEEK_SET); + buf = malloc(buf_size * sizeof(buf[0])); + fread(buf, 1, buf_size, f); + fclose(f); + + s = word_list_init(); + word_load(s, word_filename); + + fo = fopen(out_filename, "wb"); + if (!fo) { + perror(out_filename); + exit(1); + } + + for(buf_pos = 0; buf_pos < buf_size; buf_pos += word_len) { + word_len = gpt2_get_word(buf + buf_pos, buf_size - buf_pos); +#if 0 + print_word(buf + buf_pos, word_len); + printf("\n"); +#endif + /* find the longest word(s) */ + for(i = 0; i < word_len; i += len) { + for(len = word_len - i; len >= 1; len--) { + p = word_find_add(s, buf + buf_pos + i, len, FALSE); + if (p) + break; + } + assert(len >= 1); + fput_be16(fo, p - s->words); + } + } + + free(buf); + + fclose(fo); + + word_list_end(s); +} + +#define SYMB_EOT 50256 + +static void add_char(DataSymbol **pbuf, + size_t *psize, size_t *plen, DataSymbol c) +{ + size_t len = *plen, size = *psize; + if ((len + 1) > size) { + size = max_size_t(max_size_t(len + 1, 4), + size * 3 / 2); + *pbuf = realloc(*pbuf, sizeof(**pbuf) * size); + *psize = size; + } + (*pbuf)[len++] = c; + *plen = len; +} + +static void gpt2_pp_encode_buf1(WordList *s, + DataSymbol **pout_buf, + size_t *pout_buf_size, size_t *pout_buf_len, + const uint8_t *buf, size_t buf_size) +{ + size_t buf_pos, word_len, len, i; + Word *p; + + for(buf_pos = 0; buf_pos < buf_size; buf_pos += word_len) { + word_len = gpt2_get_word(buf + buf_pos, buf_size - buf_pos); +#if 0 + print_word(buf + buf_pos, word_len); + printf("\n"); +#endif + /* find the longest word(s) */ + for(i = 0; i < word_len; i += len) { + for(len = word_len - i; len >= 1; len--) { + p = word_find_add(s, buf + buf_pos + i, len, FALSE); + if (p) + break; + } + assert(len >= 1); + add_char(pout_buf, pout_buf_size, pout_buf_len, p - s->words); + } + } +} + +size_t gpt2_pp_encode_buf(WordList *s, DataSymbol **pout_buf, + const uint8_t *buf, size_t buf_size) +{ + size_t out_buf_len, out_buf_size; + DataSymbol *out_buf; + + out_buf_len = 0; + out_buf_size = 0; + out_buf = NULL; + gpt2_pp_encode_buf1(s, &out_buf, &out_buf_size, &out_buf_len, + buf, buf_size); + *pout_buf = out_buf; + return out_buf_len; +} + +void gpt2_pp_decode(const char *word_filename, + const char *in_filename, const char *out_filename) +{ + WordList *s; + FILE *f, *fo; + uint16_t c; + Word *p; + + s = word_list_init(); + word_load(s, word_filename); + + f = fopen(in_filename, "rb"); + if (!f) { + perror(in_filename); + exit(1); + } + + fo = fopen(out_filename, "wb"); + if (!fo) { + perror(out_filename); + exit(1); + } + + for(;;) { + if (fget_be16(f, &c)) + break; + if (c >= s->word_count) { + fprintf(stderr, "Invalid symbol: %d\n", c); + exit(1); + } + p = &s->words[c]; + fwrite(p->buf, 1, p->len, fo); + } + + fclose(fo); + + fclose(f); + + word_list_end(s); +} + +static struct option options[] = { + { NULL }, +}; + +/****************************************************************/ +/* text completion */ + +static int get_random_symb_topk(float *prob, size_t n_symb, int topk, + float topp, RNDState *rnd_state) +{ + NCTopKEntry *tab; + int i, c, k; + float p; + double sum; + + assert(n_symb >= 1); + + prof_start(PROF_WRITE_SYM); + k = nc_topk(&tab, &sum, prob, n_symb, topk, topp); + prof_end(PROF_WRITE_SYM); + + p = rnd_unif(rnd_state) * sum; + + sum = 0; + for(i = 0; i < k - 1; i++) { + sum += prob[tab[i].idx]; + if (p < sum) + break; + } + c = tab[i].idx; + nc_free(tab); + return c; +} + +static void dump_pred_symb(float *prob, size_t n_symb, int k, + WordList *wl) +{ +#if 0 + int *tab, i, c; + Word *wp; + + assert(n_symb >= 1); + tab = malloc(sizeof(tab[0]) * n_symb); + for(i = 0; i < n_symb; i++) + tab[i] = i; + topk_sort(tab, n_symb, prob); + + k = min_int(n_symb, k); + for(i = 0; i < k; i++) { + c = tab[i]; + printf("%d: %10.3g '", i, prob[c]); + wp = &wl->words[c]; + fwrite(wp->buf, 1, wp->len, stdout); + printf("'\n"); + } + free(tab); +#endif +} + +char *trim_text(const char *str) +{ + size_t len; + char *new_str; + while (*str == ' ') + str++; + len = strlen(str); + while (len > 0 && str[len - 1] == ' ') + len--; + new_str = malloc(len + 1); + memcpy(new_str, str, len + 1); + return new_str; +} + +TextCompleteGlobalState *text_complete_global_init(GPT2ModelEnum model, + const char *filename) +{ + WordList *wl; + TransformerModelParams p_s, *p = &p_s; + TransformerModel *s; + TextCompleteGlobalState *tcs; + char coefs_filename[128]; + + tcs = nc_mallocz(sizeof(*tcs)); + + trf_set_params(p, model); + if (!filename) { + snprintf(coefs_filename, sizeof(coefs_filename), + "gpt2_%s.bin", gpt2_model_name[model]); + filename = coefs_filename; + } + s = trf_init(p, filename); + + wl = word_list_init(); + word_load(wl, "gpt2vocab.txt"); + tcs->wl = wl; + tcs->trf_state = s; + return tcs; +} + +void text_complete_global_end(TextCompleteGlobalState *tcs) +{ + trf_end(tcs->trf_state); + word_list_end(tcs->wl); + nc_free(tcs); +} + +TextGenContext *text_complete_start(TextCompleteGlobalState *tcs, + const char *input_text, + int top_k, float top_p, float temperature, + int seed, int max_output_len) +{ + TransformerModel *s = tcs->trf_state; + WordList *wl = tcs->wl; + TextGenContext *ts; + int i, mem_len; + + ts = nc_mallocz(sizeof(*ts)); + ts->global_state = tcs; + ts->top_k = top_k; + ts->top_p = top_p; + ts->temperature = temperature; + rnd_init(&ts->rnd_state, seed); + ts->max_output_len = max_output_len; + ts->input_buf_len = gpt2_pp_encode_buf(wl, &ts->input_buf, + (const uint8_t *)input_text, + strlen(input_text)); + if (ts->input_buf_len > MAX_INITIAL_TEXT_LEN) { + memmove(ts->input_buf, ts->input_buf + ts->input_buf_len - MAX_INITIAL_TEXT_LEN, MAX_INITIAL_TEXT_LEN * sizeof(ts->input_buf[0])); + ts->input_buf_len = MAX_INITIAL_TEXT_LEN; + ts->input_buf = realloc(ts->input_buf, + ts->input_buf_len * sizeof(ts->input_buf[0])); + } + +#if 0 + for(i = 0; i < ts->input_buf_len; i++) { + printf(" %04x", ts->input_buf[i]); + } + printf("\n"); +#endif + + ts->mem_k = nc_mallocz(sizeof(ts->mem_k[0]) * s->n_layer); + ts->mem_v = nc_mallocz(sizeof(ts->mem_v[0]) * s->n_layer); + mem_len = ts->input_buf_len + max_output_len; + for(i = 0; i < s->n_layer; i++) { + ts->mem_k[i] = nc_new_tensor_3d(s->device, NC_TYPE_F32, + s->d_key, mem_len, s->n_head); + nc_tensor_set_name(ts->mem_k[i], "mem_k_%d", i); + ts->mem_v[i] = nc_new_tensor_3d(s->device, NC_TYPE_F32, + s->d_value, mem_len, s->n_head); + nc_tensor_set_name(ts->mem_v[i], "mem_v_%d", i); + } + ts->text_len = ts->input_buf_len; + ts->is_first = TRUE; + return ts; +} + +static void text_complete_symb(TextCompleteGlobalState *tcs, + TextGenContext *ts, NCTensor *logits) +{ + TransformerModel *s = tcs->trf_state; + WordList *wl = tcs->wl; + Word *wp; + NCTensorData xbuf, *x; + int c, out_len; + NCTensor *t0; + + t0 = logits; + if (ts->temperature != 1.0) + t0 = nc_mul(t0, nc_new_f32(s->device, 1.0f / ts->temperature)); + t0 = nc_soft_max(t0); + x = nc_tensor_get_data(&xbuf, t0); + + if (0) { + printf("\n"); + dump_pred_symb((float *)x->data, s->n_symbols, 10, wl); + } + c = get_random_symb_topk((float *)x->data, + s->n_symbols, ts->top_k, ts->top_p, + &ts->rnd_state); + if (c == SYMB_EOT) { + ts->out_text_len = 0; + ts->out_text[0] = '\0'; + } else { + wp = &wl->words[c]; + out_len = min_int(sizeof(ts->out_text) - 1, wp->len); + memcpy(ts->out_text, wp->buf, out_len); + ts->out_text[out_len] = '\0'; + ts->out_text_len = out_len; + } + ts->last_c = c; + + nc_free_tensor(t0); +} + +/* Note: ts_list is emptied */ +void text_complete_next(TextCompleteGlobalState *tcs, + struct list_head *ts_list) +{ + TransformerModel *s = tcs->trf_state; + int i, k; + NCTensor *output, *input; + int32_t *ptr; + struct list_head *el, *el1; + TextGenContext *ts, **ts_tab; + int batch_size; + BatchEntry tab_mem[BATCH_SIZE_MAX]; + + list_for_each_safe(el, el1, ts_list) { + ts = list_entry(el, TextGenContext, link); + if (ts->text_len >= s->n_ctx || + (ts->text_len - ts->input_buf_len) >= ts->max_output_len) { + ts->out_text_len = 0; + ts->out_text[0] = '\0'; + list_del(&ts->link); + } else if (ts->is_first) { + input = nc_new_tensor_1d(s->device, NC_TYPE_I32, ts->text_len); + ptr = nc_tensor_get_ptr(input, NULL); + for(i = 0; i < ts->text_len; i++) { + ptr[i] = ts->input_buf[i]; + } + + prof_start(PROF_EVAL); + tab_mem[0].mem_len = 0; + tab_mem[0].mem_k = ts->mem_k; + tab_mem[0].mem_v = ts->mem_v; + output = trf_eval(s, ts->text_len, 1, tab_mem, input); + prof_end(PROF_EVAL); + + text_complete_symb(tcs, ts, nc_slice_alias(output, 1, ts->text_len - 1, ts->text_len)); + nc_free_tensor(output); + + ts->text_len++; + ts->is_first = FALSE; + list_del(&ts->link); + } + } + + ts_tab = nc_mallocz(sizeof(ts_tab[0]) * BATCH_SIZE_MAX); + for(;;) { + k = 0; + list_for_each_safe(el, el1, ts_list) { + ts = list_entry(el, TextGenContext, link); + ts_tab[k++] = ts; + list_del(&ts->link); + if (k >= BATCH_SIZE_MAX) + break; + } + if (k == 0) + break; + batch_size = k; + // printf("batch_size=%d\n", k); + + for(k = 0; k < batch_size; k++) { + ts = ts_tab[k]; + tab_mem[k].mem_len = ts->text_len - 1; + tab_mem[k].mem_k = ts->mem_k; + tab_mem[k].mem_v = ts->mem_v; + } + + /* compute the next probabilities */ + input = nc_new_tensor_1d(s->device, NC_TYPE_I32, batch_size); + ptr = nc_tensor_get_ptr(input, NULL); + for(k = 0; k < batch_size; k++) { + ts = ts_tab[k]; + ptr[k] = ts->last_c; + } + + prof_start(PROF_EVAL); + output = trf_eval(s, 1, batch_size, tab_mem, input); + prof_end(PROF_EVAL); + + for(k = 0; k < batch_size; k++) { + ts = ts_tab[k]; + text_complete_symb(tcs, ts, + nc_slice_alias(output, 1, k, k + 1)); + + ts->text_len++; + ts->is_first = FALSE; + } + nc_free_tensor(output); + } + nc_free(ts_tab); +} + +void text_complete_end(TextGenContext *ts) +{ + TransformerModel *s = ts->global_state->trf_state; + int i; + + for(i = 0; i < s->n_layer; i++) { + nc_free_tensor(ts->mem_k[i]); + nc_free_tensor(ts->mem_v[i]); + } + nc_free(ts->mem_k); + nc_free(ts->mem_v); + + free(ts->input_buf); + nc_free(ts); +} + +void text_complete(GPT2ModelEnum model, const char *model_filename, + const char *input_text, + int top_k, float top_p, float temperature, + int max_output_len, int batch_size, int seed, + BOOL verbose) +{ + TextCompleteGlobalState *tcs; + TextGenContext *ts; + int count; + struct timeval tv; + const char *input_text1; + struct list_head ts_list; + int64_t ti; + + tcs = text_complete_global_init(model, model_filename); + + if (seed == 0) { + gettimeofday(&tv, NULL); + seed = tv.tv_sec + tv.tv_usec; + } + + input_text1 = trim_text(input_text); + if (input_text1[0] == '\0') + input_text1 = strdup(" "); + printf("%s", input_text1); + fflush(stdout); + prof_start(PROF_TOTAL); + if (batch_size == 0) { + ts = text_complete_start(tcs, input_text1, top_k, top_p, temperature, + seed, max_output_len); + + ti = get_time_ms(); + count = 0; + for(;;) { + init_list_head(&ts_list); + list_add_tail(&ts->link, &ts_list); + text_complete_next(tcs, &ts_list); + if (ts->out_text_len == 0) + break; + fwrite(ts->out_text, 1, ts->out_text_len, stdout); + fflush(stdout); + count++; + } + printf("\n"); + text_complete_end(ts); + } else { + TextGenContext **ts_tab; + int i; + + /* test for batch processing (the same text is generated by + each job) */ + + ts_tab = nc_mallocz(sizeof(ts_tab[0]) * batch_size); + + for(i = 0; i < batch_size; i++) { + ts = text_complete_start(tcs, input_text1, top_k, top_p, + temperature, seed, max_output_len); + ts_tab[i] = ts; + } + + ti = get_time_ms(); + count = 0; + for(;;) { + init_list_head(&ts_list); + for(i = 0; i < batch_size; i++) { + ts = ts_tab[i]; + if (ts->is_first || ts->out_text_len > 0) { + list_add_tail(&ts->link, &ts_list); + } + } + if (list_empty(&ts_list)) + break; + text_complete_next(tcs, &ts_list); + + for(i = 0; i < batch_size; i++) { + ts = ts_tab[i]; + if (ts->out_text_len > 0 && i == 0) { + fwrite(ts->out_text, 1, ts->out_text_len, stdout); + fflush(stdout); + } + } + count++; + } + printf("\n"); + + for(i = 0; i < batch_size; i++) { + ts = ts_tab[i]; + text_complete_end(ts); + } + nc_free(ts_tab); + } + ti = get_time_ms() - ti; + if (verbose) { + printf("time=%0.1f word/s\n", + (double)count / ti * 1000); + } + prof_end(PROF_TOTAL); + text_complete_global_end(tcs); + + nc_prof_dump(); +} + +/******************************************************************/ +/* short text compression */ + +/* Note: at most 31 bits are encoded. At most UTF8_CHAR_LEN_MAX bytes + are output. */ +int unicode_to_utf8(uint8_t *buf, unsigned int c) +{ + uint8_t *q = buf; + + if (c < 0x80) { + *q++ = c; + } else { + if (c < 0x800) { + *q++ = (c >> 6) | 0xc0; + } else { + if (c < 0x10000) { + *q++ = (c >> 12) | 0xe0; + } else { + if (c < 0x00200000) { + *q++ = (c >> 18) | 0xf0; + } else { + if (c < 0x04000000) { + *q++ = (c >> 24) | 0xf8; + } else if (c < 0x80000000) { + *q++ = (c >> 30) | 0xfc; + *q++ = ((c >> 24) & 0x3f) | 0x80; + } else { + return 0; + } + *q++ = ((c >> 18) & 0x3f) | 0x80; + } + *q++ = ((c >> 12) & 0x3f) | 0x80; + } + *q++ = ((c >> 6) & 0x3f) | 0x80; + } + *q++ = (c & 0x3f) | 0x80; + } + return q - buf; +} + +static const unsigned int utf8_min_code[5] = { + 0x80, 0x800, 0x10000, 0x00200000, 0x04000000, +}; + +static const unsigned char utf8_first_code_mask[5] = { + 0x1f, 0xf, 0x7, 0x3, 0x1, +}; + +/* return -1 if error. *pp is not updated in this case. max_len must + be >= 1. The maximum length for a UTF8 byte sequence is 6 bytes. */ +int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp) +{ + int l, c, b, i; + + c = *p++; + if (c < 0x80) { + *pp = p; + return c; + } + switch(c) { + case 0xc0 ... 0xdf: + l = 1; + break; + case 0xe0 ... 0xef: + l = 2; + break; + case 0xf0 ... 0xf7: + l = 3; + break; + case 0xf8 ... 0xfb: + l = 4; + break; + case 0xfc ... 0xfd: + l = 5; + break; + default: + return -1; + } + /* check that we have enough characters */ + if (l > (max_len - 1)) + return -1; + c &= utf8_first_code_mask[l - 1]; + for(i = 0; i < l; i++) { + b = *p++; + if (b < 0x80 || b >= 0xc0) + return -1; + c = (c << 6) | (b & 0x3f); + } + if (c < utf8_min_code[l - 1]) + return -1; + *pp = p; + return c; +} + +static inline int simple_get_bit(const uint8_t *data, size_t index) +{ + return (data[index >> 3] >> (7 - (index & 7))) & 1; +} + +static inline void simple_put_bit(uint8_t *data, size_t index, int bit) +{ + data[index >> 3] |= bit << (7 - (index & 7)); +} + +static uint16_t ranges[3][2] = { + { 0x3400, 0x4DB5 }, + { 0x4e00, 0x9fcf }, + { 0xAC00, 0xD7A3 }, +}; + +static int c15_to_unicode(int c) +{ + int i, n, count; + for(i = 0; i < countof(ranges); i++) { + count = ranges[i][1] - ranges[i][0] + 1; + n = count; + if (c < n) { + return ranges[i][0] + c; + } + c -= count; + } + return -1; +} + +static int unicode_to_c15(int c) +{ + int i, b; + b = 0; + for(i = 0; i < countof(ranges); i++) { + if (c >= ranges[i][0] && c <= ranges[i][1]) + return b + c - ranges[i][0]; + b += ranges[i][1] - ranges[i][0] + 1; + } + return -1; +} + +size_t convert_to_chars(char **pout_buf, uint8_t *buf, size_t n_bits) +{ + size_t idx, out_buf_len; + int c, i, l, len; + char buf1[8], *out_buf; + + out_buf = malloc(4 * ((n_bits + 14) / 15) + 1); + out_buf_len = 0; + for(idx = 0; idx < n_bits; idx += 15) { + l = min_size_t(15, n_bits - idx); + c = 0; + for(i = 0; i < l; i++) { + c |= simple_get_bit(buf, idx + i) << (14 - i); + } + c = c15_to_unicode(c); + len = unicode_to_utf8((uint8_t *)buf1, c); + memcpy(out_buf + out_buf_len, buf1, len); + out_buf_len += len; + } + out_buf[out_buf_len] = '\0'; + *pout_buf = out_buf; + return out_buf_len; +} + +/* return -1 if error */ +ssize_t convert_from_chars(uint8_t **pout_buf, const char *str) +{ + const char *str_end; + int c, i; + uint8_t *out_buf; + size_t str_len, len; + + str_len = strlen(str); + str_end = str + str_len; + /* Note: the exact length of out_buf is smaller */ + out_buf = malloc(str_len); + memset(out_buf, 0, str_len); + + len = 0; + while (*str != '\0') { + c = unicode_from_utf8((uint8_t *)str, str_end - str, (const uint8_t **)&str); + if (c < 0) + goto fail; + c = unicode_to_c15(c); + if (c < 0 || c >= 32768) + goto fail; + for(i = 0; i < 15; i++) { + simple_put_bit(out_buf, len * 15 + i, (c >> (14 - i)) & 1); + } + len++; + } + *pout_buf = out_buf; + return (len * 15 + 7) / 8; + fail: + free(out_buf); + return -1; +} + +#define LENGTH_K 2 + +int encode_length(PutBitState *pb, uint32_t val) +{ + uint32_t n, a, b, i; + a = val; + n = 1; + for(;;) { + b = 1 << (LENGTH_K * n); + if (a < b) + break; + n++; + a -= b; + } + for(i = 0; i < n - 1; i++) + put_bit_raw(pb, 0); + put_bit_raw(pb, 1); + for(i = 0; i < (LENGTH_K * n); i++) { + put_bit_raw(pb, (a >> (LENGTH_K * n - 1 - i)) & 1); + } + return n + LENGTH_K * n; +} + +int decode_length(GetBitState *gb) +{ + int n, val, a, i; + n = 1; + a = 0; + for(;;) { + if (get_bit_raw(gb)) + break; + if (n >= 10) /* arbitrary limit */ + return -1; + a += 1 << (LENGTH_K * n); + n++; + } + val = 0; + for(i = 0; i < (LENGTH_K * n); i++) { + val |= get_bit_raw(gb) << (LENGTH_K * n - 1 - i); + } + return val + a; +} + +static void realloc_buf(char **pbuf, + size_t *psize, size_t len) +{ + size_t size = *psize; + if (len > size) { + size = max_size_t(len, size * 3 / 2); + *pbuf = realloc(*pbuf, sizeof(**pbuf) * size); + *psize = size; + } +} + + +#define CTEXT_LEN_MAX 256 + +int text_decompress(TextCompleteGlobalState *tcs, + char **poutput_text, const char *input_text) +{ + TransformerModel *s = tcs->trf_state; + WordList *wl = tcs->wl; + uint8_t *data_buf; + ssize_t data_buf_len, text_len, mem_len; + GetBitState gb_s, *gb = &gb_s; + BatchEntry tab_mem[1]; + NCTensor **mem_k, **mem_v; + DataSymbol *text_buf; + NCTensorData xbuf, *x; + int c, i; + char *out_str; + size_t out_str_len, out_str_size; + + *poutput_text = NULL; + + /* XXX: handle zero length ? */ + data_buf_len = convert_from_chars(&data_buf, input_text); + if (data_buf_len < 0) + return -1; + if (data_buf_len == 0) { + *poutput_text = strdup(""); + free(data_buf); + return 0; + } +#if 0 + { + int i; + printf("data_buf="); + for(i = 0; i < data_buf_len; i++) + printf(" %02x", data_buf[i]); + printf("\n"); + } +#endif + get_bit_init(gb, data_buf, data_buf_len, NULL, NULL); + + text_len = decode_length(gb); + if (text_len < 0 || text_len > CTEXT_LEN_MAX) { + free(data_buf); + return -1; + } + text_len++; + + text_buf = nc_malloc(sizeof(text_buf[0]) * text_len); + + mem_k = nc_mallocz(sizeof(mem_k[0]) * s->n_layer); + mem_v = nc_mallocz(sizeof(mem_v[0]) * s->n_layer); + mem_len = text_len; + for(i = 0; i < s->n_layer; i++) { + mem_k[i] = nc_new_tensor_3d(s->device, NC_TYPE_F32, + s->d_key, mem_len, s->n_head); + nc_tensor_set_name(mem_k[i], "mem_k_%d", i); + mem_v[i] = nc_new_tensor_3d(s->device, NC_TYPE_F32, + s->d_value, mem_len, s->n_head); + nc_tensor_set_name(mem_v[i], "mem_v_%d", i); + } + tab_mem[0].mem_k = mem_k; + tab_mem[0].mem_v = mem_v; + + text_buf[0] = SYMB_EOT; + + for(i = 0; i < text_len - 1; i++) { + NCTensor *t0, *input; + int32_t *ptr; + + input = nc_new_tensor_1d(s->device, NC_TYPE_I32, 1); + ptr = nc_tensor_get_ptr(input, NULL); + ptr[0] = text_buf[i]; + tab_mem[0].mem_len = i; + t0 = trf_eval(s, 1, 1, tab_mem, input); + + t0 = nc_soft_max(t0); + x = nc_tensor_get_data(&xbuf, t0); + c = read_sym(gb, (float *)x->data, x->dims[0]); + text_buf[i + 1] = c; + nc_free_tensor(t0); + } + + /* convert back to a string */ + out_str = NULL; + out_str_len = 0; + out_str_size = 0; + for(i = 1; i < text_len; i++) { + Word *wp; + wp = &wl->words[text_buf[i]]; + realloc_buf(&out_str, &out_str_size, out_str_len + wp->len); + memcpy(out_str + out_str_len, wp->buf, wp->len); + out_str_len += wp->len; + } + realloc_buf(&out_str, &out_str_size, out_str_len + 1); + out_str[out_str_len] = '\0'; + + for(i = 0; i < s->n_layer; i++) { + nc_free_tensor(mem_k[i]); + nc_free_tensor(mem_v[i]); + } + nc_free(mem_k); + nc_free(mem_v); + nc_free(text_buf); + free(data_buf); + + *poutput_text = out_str; + + return 0; +} + +#define TEXT_OUTPUT_BUF_LEN 4096 + +static void text_arith_write_buf(void *opaque, const uint8_t *buf, size_t buf_size) +{ + /* we assume the output is small enough to fit the buffer */ +} + +int text_compress(TextCompleteGlobalState *tcs, + char **poutput_text, + const char *input_text, BOOL dump_stats) +{ + TransformerModel *s = tcs->trf_state; + DataSymbol *input_buf; + int i, mem_len; + NCTensorData xbuf, *x; + double n_bits; + BatchEntry tab_mem[1]; + NCTensor **mem_k, **mem_v, *output, *input; + PutBitState pb_s, *pb = &pb_s; + size_t input_buf_len, input_buf_size, out_buf_len; + uint8_t *out_buf; + char *out_str; + int32_t *ptr; + + *poutput_text = NULL; + + input_buf = NULL; + input_buf_size = 0; + input_buf_len = 0; + + add_char(&input_buf, &input_buf_size, &input_buf_len, SYMB_EOT); + gpt2_pp_encode_buf1(tcs->wl, &input_buf, &input_buf_size, &input_buf_len, + (const uint8_t *)input_text, + strlen(input_text)); + if (input_buf_len > CTEXT_LEN_MAX) { + free(input_buf); + return -1; + } + if (input_buf_len == 1) { + free(input_buf); + *poutput_text = strdup(""); + return 0; + } + +#if 0 + for(i = 0; i < input_buf_len; i++) { + printf(" %04x", input_buf[i]); + } + printf("\n"); +#endif + prof_start(PROF_EVAL); + input = nc_new_tensor_1d(s->device, NC_TYPE_I32, input_buf_len); + ptr = nc_tensor_get_ptr(input, NULL); + for(i = 0; i < input_buf_len; i++) { + ptr[i] = input_buf[i]; + } + + mem_k = nc_mallocz(sizeof(mem_k[0]) * s->n_layer); + mem_v = nc_mallocz(sizeof(mem_v[0]) * s->n_layer); + mem_len = input_buf_len; + for(i = 0; i < s->n_layer; i++) { + mem_k[i] = nc_new_tensor_3d(s->device, NC_TYPE_F32, + s->d_key, mem_len, s->n_head); + nc_tensor_set_name(mem_k[i], "mem_k_%d", i); + mem_v[i] = nc_new_tensor_3d(s->device, NC_TYPE_F32, + s->d_value, mem_len, s->n_head); + nc_tensor_set_name(mem_v[i], "mem_v_%d", i); + } + tab_mem[0].mem_len = 0; + tab_mem[0].mem_k = mem_k; + tab_mem[0].mem_v = mem_v; + + output = trf_eval(s, input_buf_len, 1, tab_mem, input); + prof_end(PROF_EVAL); + + out_buf = malloc(TEXT_OUTPUT_BUF_LEN); + put_bit_init(pb, out_buf, TEXT_OUTPUT_BUF_LEN, text_arith_write_buf, NULL); + + n_bits = encode_length(pb, input_buf_len - 1); + + for(i = 0; i < input_buf_len - 1; i++) { + double v; + NCTensor *t0; + t0 = nc_soft_max(nc_slice_alias(output, 1, i, i + 1)); + x = nc_tensor_get_data(&xbuf, t0); + write_sym(pb, (float *)x->data, x->dims[0], input_buf[i + 1]); + v = -log2(((float *)x->data)[input_buf[i + 1]]); + // printf("%d: %0.1f\n", i, v); + nc_free_tensor(t0); + n_bits += v; + } + nc_free_tensor(output); + out_buf_len = put_bit_flush(pb); +#if 0 + { + printf("out_buf="); + for(i = 0; i < (out_buf_len + 7) / 8; i++) + printf(" %02x", out_buf[i]); + printf("\n"); + } +#endif + convert_to_chars(&out_str, out_buf, out_buf_len); + if (dump_stats) { + printf("%d chars, %" PRId64 " symbols, %" PRId64 " bits (ref=%0.1f bits) (%d compressed chars)\n", + (int)strlen(input_text), + (int64_t)input_buf_len, + (int64_t)out_buf_len, + n_bits, + (int)((out_buf_len + 14) / 15)); + } + + free(out_buf); + free(input_buf); + for(i = 0; i < s->n_layer; i++) { + nc_free_tensor(mem_k[i]); + nc_free_tensor(mem_v[i]); + } + nc_free(mem_k); + nc_free(mem_v); + *poutput_text = out_str; + return 0; +} + +void text_compress_test(GPT2ModelEnum model, const char *model_filename, + const char *input_text, + BOOL is_decode, BOOL verbose) +{ + TextCompleteGlobalState *tcs; + char *out_str; + + tcs = text_complete_global_init(model, model_filename); + + if (is_decode) { + if (text_decompress(tcs, &out_str, input_text) < 0) { + printf("Error\n"); + } else { + printf("%s\n", out_str); + } + free(out_str); + } else { + if (text_compress(tcs, &out_str, input_text, verbose) < 0) { + printf("Error\n"); + } else { + printf("%s\n", out_str); + } + free(out_str); + } + text_complete_global_end(tcs); +} + +/*************************************************/ +/* file compression */ + +static uint8_t *load_file(size_t *psize, const char *filename) +{ + FILE *f; + size_t size; + uint8_t *buf; + + f = fopen(filename, "rb"); + if (!f) { + perror(filename); + exit(1); + } + fseek(f, 0, SEEK_END); + size = ftell(f); + fseek(f, 0, SEEK_SET); + buf = malloc(size + 1); + if (fread(buf, 1, size, f) != size) { + fprintf(stderr, "%s: I/O error\n", filename); + exit(1); + } + buf[size] = '\0'; + fclose(f); + *psize = size; + return buf; +} + +/* check if CRLF can be converted to LF losslessly */ +static BOOL check_lossless_crlf(const uint8_t *buf, size_t len) +{ + size_t i; + BOOL has_crlf; + has_crlf = FALSE; + for(i = 0; i < len - 1;) { + if (buf[i] == '\r' && buf[i + 1] == '\n') { + has_crlf = TRUE; + i += 2; + } else if (buf[i] == '\n') { + return FALSE; + } else { + i++; + } + } + return has_crlf; +} + +static size_t convert_crlf_to_lf(uint8_t *buf, size_t len) +{ + size_t i, j; + j = 0; + for(i = 0; i < len - 1;) { + if (buf[i] == '\r' && buf[i + 1] == '\n') + i++; + buf[j++] = buf[i++]; + } + if (i < len) + buf[j++] = buf[i++]; + return j; +} + +#define ARITH_BUF_LEN 65536 + +static void arith_write_buf(void *opaque, const uint8_t *buf, size_t buf_size) +{ + FILE *f = opaque; + fwrite(buf, 1, buf_size, f); +} + +/* XXX: should use a large batch size */ +int file_compress(TextCompleteGlobalState *tcs, + const char *infilename, const char *outfilename) +{ + TransformerModel *s = tcs->trf_state; + DataSymbol *input_buf; + int i, mem_len, len; + NCTensorData xbuf, *x; + BatchEntry tab_mem[1]; + NCTensor **mem_k, **mem_v, *output, *input; + PutBitState pb_s, *pb = &pb_s; + size_t input_buf_len, input_buf_size, input_text_len; + int64_t n_output_bits; + size_t input_buf_pos; + uint8_t *input_text, *arith_buf; + FILE *f; + BOOL convert_crlf; + int32_t *ptr; + + input_text = load_file(&input_text_len, infilename); + + convert_crlf = check_lossless_crlf(input_text, input_text_len); + // printf("convert_crlf=%d\n", convert_crlf); + + if (convert_crlf) { + input_text_len = convert_crlf_to_lf(input_text, input_text_len); + } + + input_buf = NULL; + input_buf_size = 0; + input_buf_len = 0; + + add_char(&input_buf, &input_buf_size, &input_buf_len, SYMB_EOT); + gpt2_pp_encode_buf1(tcs->wl, &input_buf, &input_buf_size, &input_buf_len, + input_text, input_text_len); + add_char(&input_buf, &input_buf_size, &input_buf_len, SYMB_EOT); + +#if 0 + for(i = 0; i < input_buf_len; i++) { + printf(" %04x", input_buf[i]); + } + printf("\n"); +#endif + prof_start(PROF_EVAL); + mem_k = nc_mallocz(sizeof(mem_k[0]) * s->n_layer); + mem_v = nc_mallocz(sizeof(mem_v[0]) * s->n_layer); + for(i = 0; i < s->n_layer; i++) { + mem_k[i] = nc_new_tensor_3d(s->device, NC_TYPE_F32, + s->d_key, s->n_ctx, s->n_head); + nc_tensor_set_name(mem_k[i], "mem_k_%d", i); + mem_v[i] = nc_new_tensor_3d(s->device, NC_TYPE_F32, + s->d_value, s->n_ctx, s->n_head); + nc_tensor_set_name(mem_v[i], "mem_v_%d", i); + } + + f = fopen(outfilename, "wb"); + if (!f) { + perror(outfilename); + exit(1); + } + + arith_buf = nc_malloc(ARITH_BUF_LEN); + put_bit_init(pb, arith_buf, ARITH_BUF_LEN, arith_write_buf, f); + + put_bit_raw(pb, convert_crlf); + + mem_len = 0; + input_buf_pos = 0; + while (input_buf_pos < (input_buf_len - 1)) { + len = min_size_t(input_buf_len - 1 - input_buf_pos, s->n_ctx - mem_len); + printf("%5.1f%% \r", (double)input_buf_pos / (double)input_buf_len * 100); + fflush(stdout); + // printf("pos=%d mem_len=%d len=%d\n", (int)input_buf_pos, mem_len, len); + + input = nc_new_tensor_1d(s->device, NC_TYPE_I32, mem_len + len); + ptr = nc_tensor_get_ptr(input, NULL); + for(i = 0; i < mem_len + len; i++) { + ptr[i] = input_buf[input_buf_pos - mem_len + i]; + } + tab_mem[0].mem_len = 0; + tab_mem[0].mem_k = mem_k; + tab_mem[0].mem_v = mem_v; + + output = trf_eval(s, mem_len + len, 1, tab_mem, input); + + for(i = 0; i < len; i++) { + NCTensor *t0; + t0 = nc_soft_max(nc_slice_alias(output, 1, mem_len + i, + mem_len + i + 1)); + x = nc_tensor_get_data(&xbuf, t0); + write_sym(pb, (float *)x->data, + x->dims[0], input_buf[input_buf_pos + i + 1]); + nc_free_tensor(t0); + } + nc_free_tensor(output); + + input_buf_pos += len; + mem_len = min_int(mem_len + len, s->n_ctx / 2); + } + + prof_end(PROF_EVAL); + + n_output_bits = put_bit_flush(pb); + + printf("-> %" PRId64 " bytes\n", (n_output_bits + 7) / 8); + fclose(f); + nc_free(arith_buf); + + free(input_buf); + for(i = 0; i < s->n_layer; i++) { + nc_free_tensor(mem_k[i]); + nc_free_tensor(mem_v[i]); + } + nc_free(mem_k); + nc_free(mem_v); + return 0; +} + +int file_decompress(TextCompleteGlobalState *tcs, + const char *infilename, const char *outfilename) +{ + TransformerModel *s = tcs->trf_state; + WordList *wl = tcs->wl; + uint8_t *data_buf; + ssize_t data_buf_len; + GetBitState gb_s, *gb = &gb_s; + BatchEntry tab_mem[1]; + NCTensor **mem_k, **mem_v, *input, *t0; + DataSymbol *text_buf; + NCTensorData xbuf, *x; + Word *wp; + int c, i, pos; + FILE *f; + BOOL convert_crlf; + int32_t *ptr; + + data_buf = load_file((size_t *)&data_buf_len, infilename); +#if 0 + { + int i; + printf("data_buf="); + for(i = 0; i < data_buf_len; i++) + printf(" %02x", data_buf[i]); + printf("\n"); + } +#endif + get_bit_init(gb, data_buf, data_buf_len, NULL, NULL); + + convert_crlf = get_bit_raw(gb); + + text_buf = nc_malloc(sizeof(text_buf[0]) * s->n_ctx); + + mem_k = nc_mallocz(sizeof(mem_k[0]) * s->n_layer); + mem_v = nc_mallocz(sizeof(mem_v[0]) * s->n_layer); + for(i = 0; i < s->n_layer; i++) { + mem_k[i] = nc_new_tensor_3d(s->device, NC_TYPE_F32, + s->d_key, s->n_ctx, s->n_head); + nc_tensor_set_name(mem_k[i], "mem_k_%d", i); + mem_v[i] = nc_new_tensor_3d(s->device, NC_TYPE_F32, + s->d_value, s->n_ctx, s->n_head); + nc_tensor_set_name(mem_v[i], "mem_v_%d", i); + } + tab_mem[0].mem_k = mem_k; + tab_mem[0].mem_v = mem_v; + + text_buf[0] = SYMB_EOT; + + f = fopen(outfilename, "wb"); + if (!f) + perror(outfilename); + + pos = 0; + for(;;) { + input = nc_new_tensor_1d(s->device, NC_TYPE_I32, 1); + ptr = nc_tensor_get_ptr(input, NULL); + ptr[0] = text_buf[pos]; + tab_mem[0].mem_len = pos; + t0 = trf_eval(s, 1, 1, tab_mem, input); + t0 = nc_soft_max(t0); + x = nc_tensor_get_data(&xbuf, t0); + c = read_sym(gb, (float *)x->data, x->dims[0]); + nc_free_tensor(t0); + if (c == SYMB_EOT) + break; + wp = &wl->words[c]; + if (convert_crlf) { + for(i = 0; i < wp->len; i++) { + if (wp->buf[i] == '\n') + fputc('\r', f); + fputc(wp->buf[i], f); + } + } else { + fwrite(wp->buf, 1, wp->len, f); + } + fflush(f); + pos++; + if (pos >= s->n_ctx) { + int n; + /* buffer full: restart with the last n_ctx / 2 symbols */ + n = s->n_ctx / 2; + for(i = 0; i < n; i++) + text_buf[i] = text_buf[pos - n + i]; + + input = nc_new_tensor_1d(s->device, NC_TYPE_I32, n); + ptr = nc_tensor_get_ptr(input, NULL); + for(i = 0; i < n; i++) + ptr[i] = text_buf[i]; + tab_mem[0].mem_len = 0; + t0 = trf_eval(s, n, 1, tab_mem, input); + nc_free_tensor(t0); + pos = n; + } + text_buf[pos] = c; + } + + fclose(f); + + for(i = 0; i < s->n_layer; i++) { + nc_free_tensor(mem_k[i]); + nc_free_tensor(mem_v[i]); + } + nc_free(mem_k); + nc_free(mem_v); + nc_free(text_buf); + free(data_buf); + + return 0; +} diff --git a/gpt2/gpt2tc.h b/gpt2/gpt2tc.h new file mode 100644 index 0000000..a110569 --- /dev/null +++ b/gpt2/gpt2tc.h @@ -0,0 +1,143 @@ +#ifndef _GPT2TC_H +#define _GPT2TC_H +#ifdef __cplusplus +extern "C" { +#endif +#include +#include +#include +#include + +#include "cutils.h" +#include "arith.h" +#include "cp_utils.h" +#include "list.h" +#include "libnc.h" + +#define MAX_INITIAL_TEXT_LEN 256 /* in symbols */ +#define MAX_OUTPUT_LEN 100 +#define DEFAULT_TOP_K 40 +#define DEFAULT_TOP_P 0.9 +#define BATCH_SIZE_MAX 16 +//#define BATCH_SIZE_MAX 1 + + +typedef uint16_t DataSymbol; + +typedef enum { + GPT2_MODEL_117M, + GPT2_MODEL_345M, + GPT2_MODEL_774M, + GPT2_MODEL_1558M, +} GPT2ModelEnum; + +typedef struct { + BOOL is_decoder; + int n_layer; + int d_model; + int n_head; + int d_key; + int d_value; + int d_inner; + int n_ctx; + int n_symbols; + uint32_t seed; +} TransformerModelParams; + +typedef struct { + NCTensor *ln_1_g, *ln_1_b; + NCTensor *attn_w, *attn_b; + NCTensor *attn_proj_w, *attn_proj_b; + + NCTensor *ln_2_g, *ln_2_b; + NCTensor *mlp_fc_w, *mlp_fc_b; + NCTensor *mlp_proj_w, *mlp_proj_b; +} TransformerLayer; + +typedef struct { + RNDState rnd_state; + NCContext *model; + NCDevice *device; + int n_layer; + int d_model; + int n_head; + int d_key; + int d_value; + int d_inner; + int n_symbols; + int n_ctx; + + /* parameters */ + NCParamList param_list; + TransformerLayer *layers; + NCTensor *wte, *wpe, *wte_trans; + NCTensor *ln_f_g, *ln_f_b; +} TransformerModel; + +typedef struct Word { + uint32_t next; /* -1 = end */ + uint32_t len; + uint8_t *buf; +} Word; + +typedef struct { + Word *words; + size_t word_count; + size_t word_size; + uint32_t *hash_table; + int hash_size; + int hash_bits; +} WordList; + +typedef struct { + TransformerModel *trf_state; + WordList *wl; +} TextCompleteGlobalState; + +typedef struct { + struct list_head link; + TextCompleteGlobalState *global_state; + int top_k; + float top_p; + float temperature; + RNDState rnd_state; + NCTensor **mem_k, **mem_v; + DataSymbol *input_buf; + int input_buf_len; + int text_len; /* current input text len */ + BOOL is_first; + int last_c; + int max_output_len; + + /* output */ + char out_text[1024]; + int out_text_len; /* 0 means end of output */ +} TextGenContext; + +GPT2ModelEnum parse_model(const char *str); +void trf_set_params(TransformerModelParams *p, GPT2ModelEnum model); +void gpt2_pp_encode(const char *word_filename, const char *in_filename, const char *out_filename); +size_t gpt2_pp_encode_buf(WordList *s, DataSymbol **pout_buf, const uint8_t *buf, size_t buf_size); +void gpt2_pp_decode(const char *word_filename, const char *in_filename, const char *out_filename); +char *trim_text(const char *str); +TextCompleteGlobalState *text_complete_global_init(GPT2ModelEnum model, const char *filename); +void text_complete_global_end(TextCompleteGlobalState *tcs); +TextGenContext *text_complete_start(TextCompleteGlobalState *tcs, const char *input_text, int top_k, float top_p, float temperature, int seed, int max_output_len); +void text_complete_next(TextCompleteGlobalState *tcs, struct list_head *ts_list); +void text_complete_end(TextGenContext *ts); +void text_complete(GPT2ModelEnum model, const char *model_filename, const char *input_text, int top_k, float top_p, float temperature, int max_output_len, int batch_size, int seed, BOOL verbose); +int unicode_to_utf8(uint8_t *buf, unsigned int c); +int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp); +size_t convert_to_chars(char **pout_buf, uint8_t *buf, size_t n_bits); +ssize_t convert_from_chars(uint8_t **pout_buf, const char *str); +int encode_length(PutBitState *pb, uint32_t val); +int decode_length(GetBitState *gb); +int text_decompress(TextCompleteGlobalState *tcs, char **poutput_text, const char *input_text); +int text_compress(TextCompleteGlobalState *tcs, char **poutput_text, const char *input_text, BOOL dump_stats); +void text_compress_test(GPT2ModelEnum model, const char *model_filename, const char *input_text, BOOL is_decode, BOOL verbose); +int file_compress(TextCompleteGlobalState *tcs, const char *infilename, const char *outfilename); +int file_decompress(TextCompleteGlobalState *tcs, const char *infilename, const char *outfilename); +#ifdef __cplusplus +} +#endif +#endif diff --git a/gpt2/gpt2vocab.txt b/gpt2/gpt2vocab.txt new file mode 100644 index 0000000000000000000000000000000000000000..62c74b2d6146b3bfd23b74ad87dc5747a0680c83 GIT binary patch literal 371149 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 MzPt)r8a#c916BBF= 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

(EgjN?JK7gMbXoGuv)t{~naQ^9A8c$cD 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 j$ +#include "cutils.h" +#include "list.h" + +/* profiling */ + +typedef enum { + PROF_EVAL, + PROF_GRAD, + PROF_SGD, + PROF_UPDATE, + PROF_WRITE_SYM, + PROF_PROBE, + PROF_TOTAL, + PROF_COUNT, +} ProfEnum; + +#ifdef PROFILE + +extern int64_t prof_cycles[PROF_COUNT]; +extern int64_t prof_samples[PROF_COUNT]; +extern int64_t prof_ops[PROF_COUNT]; + +static inline void prof_start(int idx) +{ + prof_cycles[idx] -= get_cycles(); +} + +static inline void prof_end(int idx) +{ + prof_cycles[idx] += get_cycles(); + prof_samples[idx]++; +} + +static inline void prof_end_ops(int idx, int n_ops) +{ + prof_cycles[idx] += get_cycles(); + prof_ops[idx] += n_ops; + prof_samples[idx]++; +} + +#else + +static inline void prof_start(int idx) +{ +} + +static inline void prof_end(int idx) +{ +} + +static inline void prof_end_ops(int idx, int n_ops) +{ +} + +#endif + +void nc_prof_dump(void); + +/* Automatic Differentiation Engine */ + +typedef struct NCContext NCContext; +typedef struct NCDevice NCDevice; +typedef struct NCTensor NCTensor; +typedef struct NCTensorBuffer NCTensorBuffer; +typedef struct NCNode NCNode; +typedef struct NCRNDState NCRNDState; +typedef struct NCSGDOptState NCSGDOptState; + +typedef enum { + NC_TYPE_F32, + NC_TYPE_BF16, + NC_TYPE_F16, + NC_TYPE_I8, + NC_TYPE_I16, + NC_TYPE_I32, + NC_TYPE_COUNT, +} NCTypeEnum; + +extern size_t nc_type_size_table[NC_TYPE_COUNT]; +extern const char *nc_type_name_table[NC_TYPE_COUNT]; + +#define NC_N_DIMS_MAX 4 /* maximum number of axis for tensors */ + +typedef struct NCTensorData { + NCTypeEnum item_type; + size_t item_size; + void *data; + size_t stride; /* in elements */ + size_t n_strides; /* prod(j = 1 ... n_dims, dims[j]); */ + int n_dims; + const size_t *dims; /* n_dims length */ + const size_t *strides; /* n_dims length, strides in bytes */ +} NCTensorData; + +void *nc_malloc(size_t size); +void *nc_mallocz(size_t size); +void nc_free(void *ptr); + +NCContext *nc_context_init(int nb_threads); +void nc_context_end(NCContext *m); + +NCDevice *nc_new_cpu_device(NCContext *m); +NCDevice *nc_new_cuda_device(NCContext *m, int device_index); +NCDevice *nc_new_device(NCContext *m, const char *device_name); +void nc_synchronize(NCDevice *d); + +NCTensorBuffer *nc_new_tensor_buffer(NCDevice *d, size_t size); +NCTensorBuffer *nc_dup_tensor_buffer(const NCTensorBuffer *b); +void nc_free_tensor_buffer(NCTensorBuffer *b); + +NCTensor *nc_new_tensor(NCDevice *d, NCTypeEnum type, + int n_dims, const size_t *dims); +NCTensor *nc_new_tensor_from_tensor(const NCTensor *x); +NCTensor *nc_new_tensor_from_tensor_nz(const NCTensor *x); +NCTensor *nc_new_scalar(NCDevice *d, NCTypeEnum type); +NCTensor *nc_new_tensor_1d(NCDevice *d, NCTypeEnum type, size_t len); +NCTensor *nc_new_tensor_2d(NCDevice *d, NCTypeEnum type, size_t n0, size_t n1); +NCTensor *nc_new_tensor_3d(NCDevice *d, NCTypeEnum type, + size_t n0, size_t n1, size_t n2); +NCTensor *nc_new_tensor_4d(NCDevice *d, NCTypeEnum type, + size_t n0, size_t n1, size_t n2, size_t n3); +NCTensor *__attribute__((format(printf, 2, 3))) nc_tensor_set_name(NCTensor *x, const char *fmt, ...); +NCTensor *nc_dup_tensor(const NCTensor *x); +void nc_free_tensor(NCTensor *x); +void nc_dump_tensor(const char *name, NCTensor *x, size_t n); +uint32_t nc_tensor_get_hash(NCTensor *x); +void nc_dump_tensor_hash(const char *name, const NCTensor *x); +NCNode *nc_get_node(NCTensor *x); +/* create an alias to tensor 'x1'. Gradient is not propagated thru it */ +NCTensor *nc_slice_alias(const NCTensor *x1, int axis, size_t start, size_t end); + +NCTypeEnum nc_tensor_get_item_type(const NCTensor *x); +NCTensorData *nc_tensor_get_data(NCTensorData *sd, const NCTensor *x); +/* Return a pointer to the tensor data. If *pstride is non NULL, + return the stride (in elements) of the first dimension. */ +void *nc_tensor_get_ptr(NCTensor *x, size_t *pstride); +const size_t *nc_tensor_get_dims(const NCTensor *x, int *pn_dims); +void nc_tensor_set_zero(NCTensor *y); +void nc_tensor_set_f32(NCTensor *y, float val); +NCRNDState *nc_rnd_init(NCDevice *d, uint32_t seed); +void nc_rnd_end(NCRNDState *s); +void nc_tensor_set_rnd_unif(NCTensor *y, float avg, float range, + NCRNDState *rnd_state); +void nc_tensor_set_dropout(NCTensor *y, float prob, NCRNDState *rnd_state); + +void nc_set1_i32(NCTensor *y, int n_dims, const size_t *tab_indexes, + int32_t val); +void nc_set1_i32_1d(NCTensor *y, size_t i0, int32_t val); +void nc_set1_i32_2d(NCTensor *y, size_t i0, size_t i1, int32_t val); +void nc_set1_f32(NCTensor *y, int n_dims, const size_t *tab_indexes, + float val); +void nc_set1_f32_1d(NCTensor *y, size_t i0, float val); + +int32_t nc_get1_i32(const NCTensor *x, int n_dims, const size_t *tab_indexes); +float nc_get1_f32(const NCTensor *x, int n_dims, const size_t *tab_indexes); +float nc_get1_f32_1d(const NCTensor *x, size_t i0); +float nc_get_scalar_f32(const NCTensor *x); + +void nc_tensor_copy(NCTensor *dst, NCTensor *src); +void nc_tensor_convert(NCTensor *dst, NCTensor *src); + +void nc_dump_dims(const char *str, NCTensor *x); +size_t nc_get_heap_size(NCContext *m); +NCContext *nc_get_tensor_context(const NCTensor *x); +NCTensor *nc_tensor_to_device(NCTensor *x, NCDevice *d); +NCTensor *nc_tensor_to_cpu_device(NCTensor *x); +NCDevice *nc_get_tensor_device(const NCTensor *x); + +/* element wise operations */ +NCTensor *nc_convert(NCTensor *x, NCTypeEnum new_type); +NCTensor *nc_add(NCTensor *x1, NCTensor *x2); +NCTensor *nc_neg(NCTensor *x); +NCTensor *nc_sub(NCTensor *x1, NCTensor *x2); +NCTensor *nc_mul(NCTensor *x1, NCTensor *x2); +NCTensor *nc_div(NCTensor *x1, NCTensor *x2); +NCTensor *nc_recip(NCTensor *x); +NCTensor *nc_min(NCTensor *x1, NCTensor *x2); +NCTensor *nc_max(NCTensor *x1, NCTensor *x2); +/* select x1[i] if z[i] = 0 and x2[i] otherwise */ +NCTensor *nc_select(NCTensor *z, NCTensor *x1, NCTensor *x2); +/* set y[i] = x1[i] if mask[i] = 0 and y[i] = c if mask[i] != 0. If + mask_inv is TRUE, 'mask' is inverted */ +NCTensor *nc_masked_fill(NCTensor *x, NCTensor *mask, float c, BOOL mask_inv); +NCTensor *nc_sigmoid(NCTensor *x); +NCTensor *nc_tanh(NCTensor *x); +NCTensor *nc_relu(NCTensor *x); +NCTensor *nc_gelu(NCTensor *x); +NCTensor *nc_log(NCTensor *x); +/* return cp * fg + min(1 - fg, ig) * in */ +NCTensor *nc_lstm_clamped(NCTensor *cp, NCTensor *in, + NCTensor *fg, NCTensor *ig); +/* return a * (1 - t) + b * t */ +NCTensor *nc_lerp(NCTensor *a, NCTensor *b, NCTensor *t); + +/* other operations */ +NCTensor *nc_new_vec_f32(NCDevice *d, size_t n, float val); +NCTensor *nc_new_f32(NCDevice *d, float val); +NCTensor *nc_reshape(NCTensor *x, int n_dims, const size_t *dims); +NCTensor *nc_reshape_1d(NCTensor *x, size_t n0); +NCTensor *nc_reshape_2d(NCTensor *x, size_t n0, size_t n1); +NCTensor *nc_reshape_3d(NCTensor *x, size_t n0, size_t n1, size_t n2); +NCTensor *nc_reshape_4d(NCTensor *x, size_t n0, size_t n1, size_t n2, + size_t n3); +/* duplicate the tensor by adding n_dims dimensions */ +NCTensor *nc_repeat(NCTensor *x, int n_dims, const size_t *dims); +NCTensor *nc_repeat_1d(NCTensor *x, size_t n); +/* return y0 + sum over the dimensions > n_dims of 'x'. y0 = NULL + is supported */ +NCTensor *nc_reduce_sum(NCTensor *y0, NCTensor *x, int n_dims); +/* sum all the elements of a tensor */ +NCTensor *nc_sum(NCTensor *x); +/* sum of squares */ +NCTensor *nc_reduce_sum_sqr(NCTensor *x); +NCTensor *nc_slice(NCTensor *x, int axis, size_t start, size_t end); +NCTensor *nc_slice_add(NCTensor *y0, NCTensor *x, int axis, size_t start); +/* concatenation along axis 'axis' */ +NCTensor *nc_concat(NCTensor **inputs, int n_inputs, int axis); +/* shortcut for axis = 0 */ +NCTensor *nc_vconcat(NCTensor **inputs, int n_inputs); +/* shortcut for axis = 1 */ +NCTensor *nc_hconcat(NCTensor **inputs, int n_inputs); +/* split along axis 'axis'. If tab_size = NULL, split equally. */ +void nc_split(NCTensor **tab_y, NCTensor *x, int n_outputs, + const size_t *tab_size, int axis); +/* shortcut for axis = 0 */ +void nc_vsplit(NCTensor **tab_y, NCTensor *x, int n_outputs, + const size_t *tab_size); +/* shortcut for axis = 1 */ +void nc_hsplit(NCTensor **tab_y, NCTensor *x, int n_outputs, + const size_t *tab_size); + +typedef enum { + NC_PAD_ZERO, + NC_PAD_DUP, /* duplicate element */ + /* trim types, dual to padding */ + NC_TRIM_NORMAL = NC_PAD_ZERO, + NC_TRIM_SUM, /* add trimmed elements to the edge */ +} NCPadEnum; + +/* pad (len > 0) or trim (len < 0) the axis 0 of 'x' */ +NCTensor *nc_pad(NCTensor *x, ssize_t left_len, NCPadEnum left_op, + ssize_t right_len, NCPadEnum right_op); +/* shortcut to nc_pad() */ +NCTensor *nc_resize(NCTensor *x, size_t n); + +/* if x is not contiguous then create a new contiguous tensor and copy + x to it. Otherwise, return 'x'. */ +NCTensor *nc_make_contiguous(NCTensor *x); +/* Return a new tensor sharing the same buffer as 'x' with the permuted + dimensions. axis[i] is the corresponding axis in 'x' */ +NCTensor *nc_permute_alias(NCTensor *x, int n_dims, const int *axis); +/* same as nc_permute_alias but calls nc_make_contiguous after. */ +NCTensor *nc_permute(NCTensor *x, int n_dims, const int *axis); +/* special case of nc_permute() */ +NCTensor *nc_transpose(NCTensor *x); +NCTensor *nc_matmul(NCTensor *w, NCTensor *x); +/* return w*x + y0. w and x can be optionally transposed. y0 can be NULL */ +NCTensor *nc_matmul_add(NCTensor *w, NCTensor *x, NCTensor *y0, + BOOL w_trans, BOOL x_trans); +NCTensor *nc_matmul_stride(NCTensor *w, NCTensor *x); +/* return a matrix where each column is the column x[i] of matrix 'w' */ +NCTensor *nc_get_col(NCTensor *w, NCTensor *x); +/* add the vectors 'z' at column number 'x' in matrix 'w'. */ +NCTensor *nc_add_col(NCTensor *z, NCTensor *x, NCTensor *w); +/* select the x-th element in each column of 'w' */ +NCTensor *nc_get_element(NCTensor *w, NCTensor *x); +/* add z to the x-th element in each column of 'w' */ +NCTensor *nc_add_element(NCTensor *z, NCTensor *x, NCTensor *w); +NCTensor *nc_soft_max(NCTensor *x); +/* Equivalent to y = log(get_element(x, eout)). It is expected to be + used as nc_index_log(nc_soft_max(x), eout) so that the gradient + computation is optimized. */ +NCTensor *nc_indexed_log(NCTensor *x, NCTensor *eout); +NCTensor *nc_layer_norm(NCTensor *x, float eps); +NCTensor *nc_rms_norm(NCTensor *x, float eps); +NCTensor *nc_slt_mat_set(NCTensor *x, size_t pos, float c); +/* shift the column 'i' by 'pos + i * mult' elements and pad with with zeros */ +NCTensor *nc_rel_shift(NCTensor *x, ssize_t pos, ssize_t mult); + +/* auto differentiation */ + +/* get_col_index is non NULL in the sparse gradient case */ +typedef void NCParamUpdateFunc(void *opaque, NCTensor *grad, + NCTensor *get_col_index); + +/* add a 'parameter' graph node to 'x' and return 'x'. */ +NCTensor *nc_set_param(NCTensor *x, void *opaque); +/* return a new tensor with its graph removed */ +NCTensor *nc_stop_grad(NCTensor *x); + +/* manipulation of graph nodes */ +NCNode *nc_dup_node(const NCNode *n); +void nc_free_node(NCNode *n); +void nc_combine_nodes(NCContext *m, NCNode **tab_op1, int count, + int axis, int elem_size, const size_t *tab_elem_size); +NCNode *nc_concat_node(NCContext *m, NCNode **inputs, int count, + int axis, const size_t *tab_size); +void nc_concat_optimization(NCContext *m, NCNode **concat_nodes, int count); +void nc_node_set_parent(NCNode *n, int arg_index, const NCNode *n1); +void nc_node_set_arg(NCNode *n, int arg_index, const NCTensor *x); + +#define NC_BW_KEEP_GRAD_GRAPH (1 << 0) +/* optimize the nc_get_col() gradient */ +#define NC_BW_SPARSE_GRAD (1 << 1) + +void nc_backward(const NCTensor *x, NCTensor *grad, + NCParamUpdateFunc *param_update_func, int flags); +void nc_dump_graph(NCTensor *x); + +/* utilities for function parameters */ + +typedef struct { + struct list_head link; + NCTensor **pval; /* pointer to the tensor location */ + char *name; /* parameter name */ + NCTensor *low_part; /* if BF16 parameter, additional 16 bit precision */ + NCTensor *saved_grad; /* debug */ + /* SGD opt data */ + struct SGDOptVarState *sgd_opt; +} NCParam; + +typedef struct { + struct list_head param_list; + BOOL add_graph; +} NCParamList; + +void nc_param_list_init(NCParamList *pl); +void nc_param_list_set_graph(NCParamList *pl, BOOL add_graph); +NCParam *nc_new_param_str(NCParamList *pl, NCTensor **pval, const char *str); +__attribute__((format(printf, 3, 4))) NCParam *nc_new_param(NCParamList *pl, NCTensor **pval, const char *fmt, ...); +void nc_param_list_end(NCParamList *pl); + +NCParam *nc_find_param(NCParamList *pl, const char *name); +size_t nc_get_param_count(NCParamList *pl); +void nc_save_coefs(NCParamList *pl, const char *filename); +void nc_load_coefs(NCParamList *pl, const char *filename); +void nc_save_state(NCParamList *pl, const char *filename); +void nc_load_state(NCParamList *pl, const char *filename); + +/* SGD optimizer */ + +typedef enum { + SGD_OPT_BASIC, + SGD_OPT_ADAM, + SGD_OPT_TEST, +} SGDOptAlgoEnum; + +typedef struct { + SGDOptAlgoEnum algo; + union { + struct { + float beta1; + float beta2; + float eps; + float gradient_clip; /* if != 0, per parameter gradient clipping */ + } adam; + } u; + float lr; +} SGDOptParams; + +NCSGDOptState *nc_sgd_opt_init(NCContext *m, const SGDOptParams *p); +void nc_sgd_opt_end(NCSGDOptState *s); +void sgd_opt_update_var(void *opaque, NCTensor *yg, NCTensor *get_col_index); + +/* set the SGD optimizer 's' to all parameters of the model */ +void nc_sgd_opt_set_all(NCParamList *param_list, NCSGDOptState *s); + +/* set the SGD optimizer 's' to the variable 'x'. Remove it if s = NULL */ +void nc_sgd_opt_set(NCParam *x, NCSGDOptState *s); +void nc_sgd_opt_update(NCSGDOptState *s); +/* force the learning rate */ +void nc_sgd_opt_set_lr(NCSGDOptState *s, float lr); +float nc_sgd_opt_get_lr(NCSGDOptState *s); + +/* for SGD_OPT_TEST */ +NCTensor *nc_sgd_opt_get_grad(NCParam *p); + +/* misc utilities (to be removed) */ + +typedef struct { + uint32_t seed; + /* used by Gaussian generator */ + int idx; + float y1; +} RNDState; + +typedef struct { + uint16_t u16; +} nc_float16_t; + +void rnd_init(RNDState *s, uint32_t seed); +uint32_t rnd_unif_u32(RNDState *s); +float rnd_unif(RNDState *s); +void rnd_unif_vec(float *tab, size_t n, float mu, float range, + RNDState *s); +void rnd_unif_mat(float *tab, size_t stride, size_t h, size_t w, + float mu, float sigma, RNDState *s); + +float vec_sum_f32(const float *tab, size_t n); + +typedef struct { + float val; + uint32_t idx; +} NCTopKEntry; + +/* Return the k largest values among prob[0...n_symb-1] such that k is + the largest value such that k <= topk and sum(i=0 .. k - 2, + prob[tab[i]]) < topp. + + It is assumed that prob[i] >= 0. The function returns (k, tab, + sum). 'sum' is the sum of the k returned values. 'tab' must be + freed with nc_free(). */ +int nc_topk(NCTopKEntry **ptab, double *psum, + const float *prob, size_t n, int topk, float topp); + +#endif /* LIBNC_H */ diff --git a/gpt2/list.h b/gpt2/list.h new file mode 100644 index 0000000..9ceddef --- /dev/null +++ b/gpt2/list.h @@ -0,0 +1,96 @@ +/* + * Linux klist like system + * + * Copyright (c) 2016-2017 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef LIST_H +#define LIST_H + +struct list_head { + struct list_head *prev; + struct list_head *next; +}; + +#define LIST_HEAD_INIT(el) { &(el), &(el) } + +/* return the pointer of type 'type *' containing 'el' as field 'member' */ +#define list_entry(el, type, member) \ + ((type *)((uint8_t *)(el) - offsetof(type, member))) + +static inline void init_list_head(struct list_head *head) +{ + head->prev = head; + head->next = head; +} + +/* insert 'el' between 'prev' and 'next' */ +static inline void __list_add(struct list_head *el, + struct list_head *prev, struct list_head *next) +{ + prev->next = el; + el->prev = prev; + el->next = next; + next->prev = el; +} + +/* add 'el' at the head of the list 'head' (= after element head) */ +static inline void list_add(struct list_head *el, struct list_head *head) +{ + __list_add(el, head, head->next); +} + +/* add 'el' at the end of the list 'head' (= before element head) */ +static inline void list_add_tail(struct list_head *el, struct list_head *head) +{ + __list_add(el, head->prev, head); +} + +static inline void list_del(struct list_head *el) +{ + struct list_head *prev, *next; + prev = el->prev; + next = el->next; + prev->next = next; + next->prev = prev; + el->prev = NULL; /* fail safe */ + el->next = NULL; /* fail safe */ +} + +static inline int list_empty(struct list_head *el) +{ + return el->next == el; +} + +#define list_for_each(el, head) \ + for(el = (head)->next; el != (head); el = el->next) + +#define list_for_each_safe(el, el1, head) \ + for(el = (head)->next, el1 = el->next; el != (head); \ + el = el1, el1 = el->next) + +#define list_for_each_prev(el, head) \ + for(el = (head)->prev; el != (head); el = el->prev) + +#define list_for_each_prev_safe(el, el1, head) \ + for(el = (head)->prev, el1 = el->prev; el != (head); \ + el = el1, el1 = el->prev) + +#endif /* LIST_H */ diff --git a/gpt2/readme.txt b/gpt2/readme.txt new file mode 100644 index 0000000..3f95757 --- /dev/null +++ b/gpt2/readme.txt @@ -0,0 +1,86 @@ +GPT-2 text completion and compression demo +========================================== + +1) Usage +-------- + +Extract the 117M GPT-2 model to the gpt2tc directory: + +tar xtf gpt2tc-117M.tar.gz + +Text completion example: + +./gpt2tc g "Hello, my name is" + +Use more CPU cores (only faster on server CPUs): + +./gpt2tc -T 4 g "Hello, my name is" + +Short Text compression and decompression example: + +./gpt2tc cs "Hello, how are you ?" + +./gpt2tc ds "姯敳痪" + +Text compression example: + +./gpt2tc c in.txt out.bin + +Decompression: + +./gpt2tc d out.bin out.txt + +2) Using larger models +---------------------- + +The smallest GPT-2 model (117M) is provided in a separate +archive. Larger models can be built by downloading the TensorFlow +parameters and converting them with the attached script. Example: + +# download the model to models/345M +./download_model.sh 345M + +# convert it to the gpt2tc format: +python3 gpt2convert.py models/345M gpt2_345M.bin + +# use it +./gpt2tc -m 345M g "Hello, how are you ?" + +3) Compression results +---------------------- + +File Model Original size Compr. size Ratio CMIX v18 + #params (bytes) (bytes) (bpb) ratio (bpb) +book1 117M 768771 152283 1.58 1.82 +book1 345M 768771 142183 1.48 +book1 774M 768771 137562 1.43 +book1 1558M 768771 134217 1.40 + +alice29.txt 117M 152089 23615 1.24 1.65 +alice29.txt 345M 152089 20587 1.08 +alice29.txt 774M 152089 19096 1.00 +alice29.txt 1558M 152089 17382 0.91 + +enwik5 117M 100000 14875 1.19 1.60 +enwik5 345M 100000 13511 1.08 +enwik5 774M 100000 13240 1.06 +enwik5 1558M 100000 12918 1.03 + +Notes: +- book1 comes from the Calgary corpus. +- alice29.txt comes from the Canterbury corpus. +- enwik5 contains the first 100000 bytes of the English + Wikipedia dump of March 3, 2006 + (http://mattmahoney.net/dc/textdata.html). +- For best performance, use the UTF-8 encoding and don't mix CRLF and + LF line breaks. +- For reference, the results of CMIX + (http://www.byronknoll.com/cmix.html) are provided. + +4) More information +------------------- + +This demo has no external dependency. It is written in C and uses the +LibNC library for tensor manipulation. The CPU must support AVX2. + +A similar program is used for http://textsynth.org/ diff --git a/justlm.hpp b/justlm.hpp new file mode 100644 index 0000000..4347ca7 --- /dev/null +++ b/justlm.hpp @@ -0,0 +1,54 @@ +#ifndef LLM_H +#define LLM_H +#include +#include +#include +#include +#include +#include + + +class LLM { + struct { + int32_t seed; // RNG seed + int32_t n_threads = static_cast(std::thread::hardware_concurrency()) / 2; + union { + int32_t n_ctx; // Context size, llama.cpp specific + int32_t n_prompt = -1; // Prompt size, gpt2 specific + }; + int32_t n_batch = 8; // Batch size, unused + + int32_t top_k = 40; + float top_p = 0.5f; + float temp = 0.72f; + } params; + + struct State *state; + + void init(const std::string& weights_path); + + static + bool ends_with(std::string_view str, std::string_view suffix); + +public: + struct Exception : public std::runtime_error { + using std::runtime_error::runtime_error; + }; + struct ContextLengthException : public Exception { + ContextLengthException() : Exception("Max. context length exceeded") {} + }; + + LLM(const std::string& weights_path, int32_t seed = 0) { + // Set random seed + params.seed = seed?seed:time(NULL); + + // Initialize llm + init(weights_path); + } + ~LLM(); + + void append(std::string_view prompt, const std::function& on_tick = nullptr); + + std::string run(std::string_view end, const std::function& on_tick = nullptr); +}; +#endif // LLM_H diff --git a/libjustlm_core.cpp b/libjustlm_core.cpp new file mode 100644 index 0000000..493313c --- /dev/null +++ b/libjustlm_core.cpp @@ -0,0 +1,9 @@ +#include "justlm.hpp" + +#include + + + +bool LLM::ends_with(std::string_view str, std::string_view suffix) { + return str.size() >= suffix.size() && 0 == str.compare(str.size()-suffix.size(), suffix.size(), suffix); +} diff --git a/libjustlm_gpt2.cpp b/libjustlm_gpt2.cpp new file mode 100644 index 0000000..c29f42c --- /dev/null +++ b/libjustlm_gpt2.cpp @@ -0,0 +1,80 @@ +#include "justlm.hpp" +#include "gpt2/gpt2tc.h" + +#include +#include + + +struct State { + std::string prompt; + std::string model_path; + GPT2ModelEnum model; +} state; + + + +void LLM::init(const std::string& weights_path) { + state->model_path = weights_path; + // Get weight file size + auto weights_size = std::filesystem::file_size(weights_path); + // Determine weight size + switch (weights_size) { + case 250700242: state->model = GPT2_MODEL_117M; break; + case 3120522738: state->model = GPT2_MODEL_1558M; break; + case 712396722: state->model = GPT2_MODEL_345M; break; + case 1551900050: state->model = GPT2_MODEL_774M; break; + default: throw Exception("Unknown model size"); + } +} + +LLM::~LLM() { + delete state; +} + +void LLM::append(std::string_view prompt, const std::function &on_tick) { + state->prompt.append(prompt); + std::cout << prompt << std::endl; +} + +std::string LLM::run(std::string_view end, const std::function &on_tick) { + std::string fres; + TextCompleteGlobalState *tcs; + TextGenContext *ts; + int count; + struct timeval tv; + struct list_head ts_list; + + // Initialize completion + tcs = text_complete_global_init(state->model, state->model_path.c_str()); + + // Run completion + ts = text_complete_start(tcs, state->prompt.c_str(), params.top_k, params.top_p, params.temp, + params.seed, params.n_prompt>0?params.n_prompt:0xfffffff - state->prompt.size()); + bool abort = false; + while (!abort && !ends_with(fres, end)) { + // Run completion + init_list_head(&ts_list); + list_add_tail(&ts->link, &ts_list); + text_complete_next(tcs, &ts_list); + if (ts->out_text_len == 0) + break; + auto str = std::string_view{ts->out_text, static_cast(ts->out_text_len)}; + + // Append result to fres + fres.append(str); + + // Tick + if (on_tick && !on_tick(std::string(str).c_str()) /*Huge overhead in favor of llama.cpp*/) abort = true; + } + // End completion + text_complete_end(ts); + + text_complete_global_end(tcs); + + // Create final string TODO: Could be optimized + state->prompt.append(fres); + fres = std::string(fres.data(), fres.size()-end.size()); + + // Return final string + return fres; +} diff --git a/libjustlm_llama.cpp b/libjustlm_llama.cpp new file mode 100644 index 0000000..c3e2981 --- /dev/null +++ b/libjustlm_llama.cpp @@ -0,0 +1,115 @@ +#include "justlm.hpp" + +#include +#include + + +struct State { + llama_context *ctx = nullptr; + std::string prompt; + std::vector embd; + int n_ctx; + std::string last_result; +} state; + + + +void LLM::init(const std::string& weights_path) { + // Allocate state + state = new State; + + // Get llama parameters + auto lparams = llama_context_default_params(); + lparams.seed = params.seed; + lparams.n_ctx = params.n_ctx>0?params.n_ctx:2024; + + // Create context + state->ctx = llama_init_from_file(weights_path.c_str(), lparams); + if (!state->ctx) { + throw Exception("Failed to initialize llama from file"); + } + + // Initialize some variables + state->n_ctx = llama_n_ctx(state->ctx); +} + +LLM::~LLM() { + if (state->ctx) llama_free(state->ctx); + delete state; +} + +void LLM::append(std::string_view prompt, const std::function &on_tick) { + // Check if prompt was empty + const bool was_empty = state->prompt.empty(); + + // Append to current prompt + state->prompt.append(prompt); + + // Resize buffer for tokens + const auto old_token_count = state->embd.size(); + state->embd.resize(old_token_count+state->prompt.size()+1); + + // Run tokenizer + const auto token_count = llama_tokenize(state->ctx, prompt.data(), state->embd.data()+old_token_count, state->embd.size()-old_token_count, was_empty); + state->embd.resize(old_token_count+token_count); + + // Make sure limit is far from being hit + if (state->embd.size() > state->n_ctx-6) { + // Yup. *this MUST be decomposed now. + throw ContextLengthException(); + } + + // Evaluate new tokens + // TODO: Larger batch size + std::cout << "Context size: " << old_token_count << '+' << token_count << '=' << state->embd.size() << '/' << state->n_ctx << std::endl; + for (int it = old_token_count; it != state->embd.size(); it++) { + std::cout << llama_token_to_str(state->ctx, state->embd.data()[it]) << std::flush; + llama_eval(state->ctx, state->embd.data()+it, 1, it, params.n_threads); + + // Tick + if (on_tick) { + // Calculate progress + auto progress = float(it-old_token_count) / (state->embd.size()-old_token_count) * 100.f; + // Run callback + if (!on_tick(progress)) break; + } + } + std::cout << std::endl; +} + +std::string LLM::run(std::string_view end, const std::function &on_tick) { + std::string fres; + + // Loop until done + bool abort = false; + while (!abort && !ends_with(fres, end)) { + // Sample top p and top k + const auto id = llama_sample_top_p_top_k(state->ctx, nullptr, 0, params.top_k, params.top_p, params.temp, 1.0f); + + // Add token + state->embd.push_back(id); + + // Get token as string + const auto str = llama_token_to_str(state->ctx, id); + + // Debug + std::cout << str << std::flush; + + // Append string to function result + fres.append(str); + + // Evaluate token + // TODO: Respect batch size + llama_eval(state->ctx, state->embd.data()+state->embd.size()-1, 1, state->embd.size()-1, params.n_threads); + + // Tick + if (on_tick && !on_tick(str)) abort = true; + } + + // Create final string TODO: Could be optimized + state->prompt.append(fres); + fres = std::string(fres.data(), fres.size()-end.size()); + + // Return final string + return fres; +} diff --git a/llama.cpp b/llama.cpp new file mode 160000 index 0000000..9cbc404 --- /dev/null +++ b/llama.cpp @@ -0,0 +1 @@ +Subproject commit 9cbc404ba6699a9ba4925ea25a60552b13491c7a diff --git a/test.cpp b/test.cpp new file mode 100644 index 0000000..94f5868 --- /dev/null +++ b/test.cpp @@ -0,0 +1,12 @@ +#include "ai.hpp" + +#include + + + +int main() { + Ai ai; + std::cout << "Completing \"she replied that\"..." << std::endl; + std::cout << "Using model " << ai.model_name << "..." << std::endl; + std::cout << "> she replied that" << ai.complete("she replied that", '\n') << std::endl; +}