Merge remote-tracking branch 'origin/master' into sl/rename-common-funcs
This commit is contained in:
commit
6bafc50650
5 changed files with 181 additions and 135 deletions
|
@ -63,7 +63,7 @@ option(LLAMA_SANITIZE_ADDRESS "llama: enable address sanitizer" OFF)
|
||||||
option(LLAMA_SANITIZE_UNDEFINED "llama: enable undefined sanitizer" OFF)
|
option(LLAMA_SANITIZE_UNDEFINED "llama: enable undefined sanitizer" OFF)
|
||||||
|
|
||||||
# utils
|
# utils
|
||||||
option(LLAMA_BUILD_COMMON "llama: build common utils library" ON)
|
option(LLAMA_BUILD_COMMON "llama: build common utils library" ${LLAMA_STANDALONE})
|
||||||
|
|
||||||
# extra artifacts
|
# extra artifacts
|
||||||
option(LLAMA_BUILD_TESTS "llama: build tests" ${LLAMA_STANDALONE})
|
option(LLAMA_BUILD_TESTS "llama: build tests" ${LLAMA_STANDALONE})
|
||||||
|
@ -201,12 +201,12 @@ if (LLAMA_BUILD_COMMON)
|
||||||
add_subdirectory(common)
|
add_subdirectory(common)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (LLAMA_BUILD_TESTS AND NOT CMAKE_JS_VERSION)
|
if (LLAMA_BUILD_COMMON AND LLAMA_BUILD_TESTS AND NOT CMAKE_JS_VERSION)
|
||||||
include(CTest)
|
include(CTest)
|
||||||
add_subdirectory(tests)
|
add_subdirectory(tests)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (LLAMA_BUILD_EXAMPLES)
|
if (LLAMA_BUILD_COMMON AND LLAMA_BUILD_EXAMPLES)
|
||||||
add_subdirectory(examples)
|
add_subdirectory(examples)
|
||||||
add_subdirectory(pocs)
|
add_subdirectory(pocs)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -18,6 +18,7 @@ android {
|
||||||
}
|
}
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
|
arguments += "-DLLAMA_BUILD_COMMON=ON"
|
||||||
arguments += "-DCMAKE_BUILD_TYPE=Release"
|
arguments += "-DCMAKE_BUILD_TYPE=Release"
|
||||||
cppFlags += listOf()
|
cppFlags += listOf()
|
||||||
arguments += listOf()
|
arguments += listOf()
|
||||||
|
|
|
@ -169,7 +169,7 @@ static void process_logits(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
const results_log_softmax results = log_softmax(n_vocab, logits + i*n_vocab, tokens[i+1]);
|
const results_log_softmax results = log_softmax(n_vocab, logits + size_t(i)*n_vocab, tokens[i+1]);
|
||||||
const double v = -results.log_softmax;
|
const double v = -results.log_softmax;
|
||||||
local_nll += v;
|
local_nll += v;
|
||||||
local_nll2 += v*v;
|
local_nll2 += v*v;
|
||||||
|
@ -203,7 +203,7 @@ static void process_logits(std::ostream& out, int n_vocab, const float * logits,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
const double v = log_softmax(n_vocab, logits + i*n_vocab, log_probs.data() + i*nv, tokens[i+1]);
|
const double v = log_softmax(n_vocab, logits + size_t(i)*n_vocab, log_probs.data() + i*nv, tokens[i+1]);
|
||||||
local_nll += v;
|
local_nll += v;
|
||||||
local_nll2 += v*v;
|
local_nll2 += v*v;
|
||||||
}
|
}
|
||||||
|
@ -281,7 +281,9 @@ static std::pair<double, float> log_softmax(int n_vocab, const float * logits, c
|
||||||
kld.sum_kld += sum;
|
kld.sum_kld += sum;
|
||||||
kld.sum_kld2 += sum*sum;
|
kld.sum_kld2 += sum*sum;
|
||||||
++kld.count;
|
++kld.count;
|
||||||
if (imax == imax_base) ++kld.n_same_top;
|
if (imax == imax_base) {
|
||||||
|
++kld.n_same_top;
|
||||||
|
}
|
||||||
|
|
||||||
const float p_base = expf(-nll_base);
|
const float p_base = expf(-nll_base);
|
||||||
const float p = expf(-nll);
|
const float p = expf(-nll);
|
||||||
|
@ -323,7 +325,7 @@ static void process_logits(int n_vocab, const float * logits, const int * tokens
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
std::pair<double, float> v = log_softmax(n_vocab, logits + i*n_vocab, base_log_probs.data() + i*nv, tokens[i+1], local_kld);
|
std::pair<double, float> v = log_softmax(n_vocab, logits + size_t(i)*n_vocab, base_log_probs.data() + i*nv, tokens[i+1], local_kld);
|
||||||
kld_values[i] = (float)v.first;
|
kld_values[i] = (float)v.first;
|
||||||
p_diff_values[i] = v.second;
|
p_diff_values[i] = v.second;
|
||||||
}
|
}
|
||||||
|
@ -383,9 +385,10 @@ static results_perplexity perplexity_v2(llama_context * ctx, const common_params
|
||||||
const int n_chunk_max = (tokens.size() - calc_chunk + params.ppl_stride - 1) / params.ppl_stride;
|
const int n_chunk_max = (tokens.size() - calc_chunk + params.ppl_stride - 1) / params.ppl_stride;
|
||||||
|
|
||||||
const int n_chunk = params.n_chunks < 0 ? n_chunk_max : std::min(params.n_chunks, n_chunk_max);
|
const int n_chunk = params.n_chunks < 0 ? n_chunk_max : std::min(params.n_chunks, n_chunk_max);
|
||||||
const int n_vocab = llama_n_vocab(llama_get_model(ctx));
|
|
||||||
const int n_batch = params.n_batch;
|
const int n_batch = params.n_batch;
|
||||||
|
|
||||||
|
const int n_vocab = llama_n_vocab(llama_get_model(ctx));
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
double nll = 0.0;
|
double nll = 0.0;
|
||||||
|
|
||||||
|
@ -424,8 +427,8 @@ static results_perplexity perplexity_v2(llama_context * ctx, const common_params
|
||||||
tokens[batch_start] = llama_token_bos(llama_get_model(ctx));
|
tokens[batch_start] = llama_token_bos(llama_get_model(ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto batch_logits = llama_get_logits(ctx);
|
const auto * batch_logits = llama_get_logits(ctx);
|
||||||
logits.insert(logits.end(), batch_logits, batch_logits + batch_size * n_vocab);
|
logits.insert(logits.end(), batch_logits, batch_logits + size_t(batch_size) * n_vocab);
|
||||||
|
|
||||||
if (j == 0) {
|
if (j == 0) {
|
||||||
tokens[batch_start] = token_org;
|
tokens[batch_start] = token_org;
|
||||||
|
@ -447,11 +450,10 @@ static results_perplexity perplexity_v2(llama_context * ctx, const common_params
|
||||||
|
|
||||||
//LOG_DBG("%s: using tokens %d...%d\n",__func__,params.n_ctx - params.ppl_stride + start, params.n_ctx + start);
|
//LOG_DBG("%s: using tokens %d...%d\n",__func__,params.n_ctx - params.ppl_stride + start, params.n_ctx + start);
|
||||||
for (int j = n_ctx - params.ppl_stride - 1; j < n_ctx - 1; ++j) {
|
for (int j = n_ctx - params.ppl_stride - 1; j < n_ctx - 1; ++j) {
|
||||||
|
|
||||||
// Calculate probability of next token, given the previous ones.
|
// Calculate probability of next token, given the previous ones.
|
||||||
const std::vector<float> tok_logits(
|
const std::vector<float> tok_logits(
|
||||||
logits.begin() + (j + 0) * n_vocab,
|
logits.begin() + size_t(j + 0) * n_vocab,
|
||||||
logits.begin() + (j + 1) * n_vocab);
|
logits.begin() + size_t(j + 1) * n_vocab);
|
||||||
|
|
||||||
const float prob = softmax(tok_logits)[tokens[start + j + 1]];
|
const float prob = softmax(tok_logits)[tokens[start + j + 1]];
|
||||||
logit_history[start + j + 1] = tok_logits[tokens[start + j + 1]];
|
logit_history[start + j + 1] = tok_logits[tokens[start + j + 1]];
|
||||||
|
@ -521,9 +523,10 @@ static results_perplexity perplexity(llama_context * ctx, const common_params &
|
||||||
const int n_chunk_max = tokens.size() / n_ctx;
|
const int n_chunk_max = tokens.size() / n_ctx;
|
||||||
|
|
||||||
const int n_chunk = params.n_chunks < 0 ? n_chunk_max : std::min(params.n_chunks, n_chunk_max);
|
const int n_chunk = params.n_chunks < 0 ? n_chunk_max : std::min(params.n_chunks, n_chunk_max);
|
||||||
const int n_vocab = llama_n_vocab(llama_get_model(ctx));
|
|
||||||
const int n_batch = params.n_batch;
|
const int n_batch = params.n_batch;
|
||||||
|
|
||||||
|
const int n_vocab = llama_n_vocab(llama_get_model(ctx));
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
double nll = 0.0;
|
double nll = 0.0;
|
||||||
double nll2 = 0.0;
|
double nll2 = 0.0;
|
||||||
|
@ -538,7 +541,7 @@ static results_perplexity perplexity(llama_context * ctx, const common_params &
|
||||||
|
|
||||||
std::vector<float> logits;
|
std::vector<float> logits;
|
||||||
if (num_batches > 1) {
|
if (num_batches > 1) {
|
||||||
logits.reserve((size_t)n_ctx * n_vocab);
|
logits.reserve(size_t(n_ctx) * n_vocab);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INF("%s: calculating perplexity over %d chunks, n_ctx=%d, batch_size=%d, n_seq=%d\n", __func__, n_chunk, n_ctx, n_batch, n_seq);
|
LOG_INF("%s: calculating perplexity over %d chunks, n_ctx=%d, batch_size=%d, n_seq=%d\n", __func__, n_chunk, n_ctx, n_batch, n_seq);
|
||||||
|
@ -620,7 +623,7 @@ static results_perplexity perplexity(llama_context * ctx, const common_params &
|
||||||
|
|
||||||
if (num_batches > 1 && n_outputs > 0) {
|
if (num_batches > 1 && n_outputs > 0) {
|
||||||
const auto * batch_logits = llama_get_logits(ctx);
|
const auto * batch_logits = llama_get_logits(ctx);
|
||||||
logits.insert(logits.end(), batch_logits, batch_logits + n_outputs * n_vocab);
|
logits.insert(logits.end(), batch_logits, batch_logits + size_t(n_outputs) * n_vocab);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -661,7 +664,9 @@ static results_perplexity perplexity(llama_context * ctx, const common_params &
|
||||||
} else {
|
} else {
|
||||||
double av = nll/count;
|
double av = nll/count;
|
||||||
double av2 = nll2/count - av*av;
|
double av2 = nll2/count - av*av;
|
||||||
if (av2 > 0) av2 = sqrt(av2/(count-1));
|
if (av2 > 0) {
|
||||||
|
av2 = sqrt(av2/(count-1));
|
||||||
|
}
|
||||||
LOG("%8d %.4lf %4lf %4lf\n", i*n_ctx, std::exp(nll / count), av, av2);
|
LOG("%8d %.4lf %4lf %4lf\n", i*n_ctx, std::exp(nll / count), av, av2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -686,10 +691,10 @@ static results_perplexity perplexity(llama_context * ctx, const common_params &
|
||||||
return {tokens, ppl, logit_history, prob_history};
|
return {tokens, ppl, logit_history, prob_history};
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool decode_helper(llama_context * ctx, llama_batch & batch, std::vector<float> & batch_logits, int32_t n_batch, int32_t n_vocab) {
|
static bool decode_helper(llama_context * ctx, llama_batch & batch, std::vector<float> & batch_logits, int n_batch, int n_vocab) {
|
||||||
int prev_outputs = 0;
|
int prev_outputs = 0;
|
||||||
for (int32_t i = 0; i < (int32_t) batch.n_tokens; i += n_batch) {
|
for (int i = 0; i < (int) batch.n_tokens; i += n_batch) {
|
||||||
const int32_t n_tokens = std::min(n_batch, (int32_t) (batch.n_tokens - i));
|
const int n_tokens = std::min<int>(n_batch, batch.n_tokens - i);
|
||||||
|
|
||||||
llama_batch batch_view = {
|
llama_batch batch_view = {
|
||||||
n_tokens,
|
n_tokens,
|
||||||
|
@ -713,7 +718,7 @@ static bool decode_helper(llama_context * ctx, llama_batch & batch, std::vector<
|
||||||
n_outputs += batch_view.logits[i] != 0;
|
n_outputs += batch_view.logits[i] != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(batch_logits.data() + prev_outputs*n_vocab, llama_get_logits(ctx), n_outputs*n_vocab*sizeof(float));
|
memcpy(batch_logits.data() + size_t(prev_outputs)*n_vocab, llama_get_logits(ctx), size_t(n_outputs)*n_vocab*sizeof(float));
|
||||||
|
|
||||||
prev_outputs += n_outputs;
|
prev_outputs += n_outputs;
|
||||||
}
|
}
|
||||||
|
@ -728,7 +733,9 @@ static void compute_logprobs(const float * batch_logits, int n_vocab, std::vecto
|
||||||
if (eval_results.size() != eval_pairs.size()) {
|
if (eval_results.size() != eval_pairs.size()) {
|
||||||
eval_results.resize(eval_pairs.size());
|
eval_results.resize(eval_pairs.size());
|
||||||
}
|
}
|
||||||
if (eval_pairs.empty()) return;
|
if (eval_pairs.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
size_t max_threads = std::min((eval_pairs.size() + K_TOKEN_CHUNK - 1)/K_TOKEN_CHUNK, workers.size());
|
size_t max_threads = std::min((eval_pairs.size() + K_TOKEN_CHUNK - 1)/K_TOKEN_CHUNK, workers.size());
|
||||||
|
|
||||||
|
@ -736,11 +743,13 @@ static void compute_logprobs(const float * batch_logits, int n_vocab, std::vecto
|
||||||
auto compute = [&counter, &eval_pairs, &eval_results, batch_logits, n_vocab] () {
|
auto compute = [&counter, &eval_pairs, &eval_results, batch_logits, n_vocab] () {
|
||||||
float local_logprobs[K_TOKEN_CHUNK];
|
float local_logprobs[K_TOKEN_CHUNK];
|
||||||
while (true) {
|
while (true) {
|
||||||
size_t first = counter.fetch_add(K_TOKEN_CHUNK, std::memory_order_relaxed);
|
const size_t first = counter.fetch_add(K_TOKEN_CHUNK, std::memory_order_relaxed);
|
||||||
if (first >= eval_results.size()) break;
|
if (first >= eval_results.size()) {
|
||||||
size_t last = std::min(first + K_TOKEN_CHUNK, eval_results.size());
|
break;
|
||||||
|
}
|
||||||
|
const size_t last = std::min(first + K_TOKEN_CHUNK, eval_results.size());
|
||||||
for (size_t i = first; i < last; ++i) {
|
for (size_t i = first; i < last; ++i) {
|
||||||
auto logits = batch_logits + eval_pairs[i].first * n_vocab;
|
const auto * logits = batch_logits + eval_pairs[i].first * n_vocab;
|
||||||
float max_logit = logits[0];
|
float max_logit = logits[0];
|
||||||
for (int j = 1; j < n_vocab; ++j) {
|
for (int j = 1; j < n_vocab; ++j) {
|
||||||
max_logit = std::max(max_logit, logits[j]);
|
max_logit = std::max(max_logit, logits[j]);
|
||||||
|
@ -877,10 +886,11 @@ static void hellaswag_score(llama_context * ctx, const common_params & params) {
|
||||||
|
|
||||||
double acc = 0.0f;
|
double acc = 0.0f;
|
||||||
|
|
||||||
const int n_vocab = llama_n_vocab(llama_get_model(ctx));
|
|
||||||
const int n_ctx = llama_n_ctx(ctx);
|
const int n_ctx = llama_n_ctx(ctx);
|
||||||
const int n_batch = params.n_batch;
|
const int n_batch = params.n_batch;
|
||||||
|
|
||||||
|
const int n_vocab = llama_n_vocab(llama_get_model(ctx));
|
||||||
|
|
||||||
const int max_tasks_per_batch = 32;
|
const int max_tasks_per_batch = 32;
|
||||||
const int max_seq = std::min(4*max_tasks_per_batch, (int) llama_n_seq_max(ctx));
|
const int max_seq = std::min(4*max_tasks_per_batch, (int) llama_n_seq_max(ctx));
|
||||||
|
|
||||||
|
@ -888,7 +898,7 @@ static void hellaswag_score(llama_context * ctx, const common_params & params) {
|
||||||
|
|
||||||
std::vector<float> tok_logits(n_vocab);
|
std::vector<float> tok_logits(n_vocab);
|
||||||
// TODO: this could be made smaller; it's currently the worst-case size
|
// TODO: this could be made smaller; it's currently the worst-case size
|
||||||
std::vector<float> batch_logits(n_vocab*n_ctx);
|
std::vector<float> batch_logits(size_t(n_ctx)*n_vocab);
|
||||||
|
|
||||||
std::vector<std::pair<size_t, llama_token>> eval_pairs;
|
std::vector<std::pair<size_t, llama_token>> eval_pairs;
|
||||||
std::vector<float> eval_results;
|
std::vector<float> eval_results;
|
||||||
|
@ -975,7 +985,7 @@ static void hellaswag_score(llama_context * ctx, const common_params & params) {
|
||||||
auto & hs_cur = hs_data[i];
|
auto & hs_cur = hs_data[i];
|
||||||
|
|
||||||
// get the logits of the last token of the common prefix
|
// get the logits of the last token of the common prefix
|
||||||
std::memcpy(tok_logits.data(), batch_logits.data() + n_vocab*hs_cur.i_logits, n_vocab*sizeof(float));
|
std::memcpy(tok_logits.data(), batch_logits.data() + hs_cur.i_logits*n_vocab, n_vocab*sizeof(float));
|
||||||
|
|
||||||
const auto first_probs = softmax(tok_logits);
|
const auto first_probs = softmax(tok_logits);
|
||||||
|
|
||||||
|
@ -1158,10 +1168,11 @@ static void winogrande_score(llama_context * ctx, const common_params & params)
|
||||||
|
|
||||||
LOG_INF("%s : calculating winogrande score over selected tasks.\n", __func__);
|
LOG_INF("%s : calculating winogrande score over selected tasks.\n", __func__);
|
||||||
|
|
||||||
const int n_vocab = llama_n_vocab(llama_get_model(ctx));
|
|
||||||
const int n_ctx = llama_n_ctx(ctx);
|
const int n_ctx = llama_n_ctx(ctx);
|
||||||
const int n_batch = params.n_batch;
|
const int n_batch = params.n_batch;
|
||||||
|
|
||||||
|
const int n_vocab = llama_n_vocab(llama_get_model(ctx));
|
||||||
|
|
||||||
const int max_tasks_per_batch = 128;
|
const int max_tasks_per_batch = 128;
|
||||||
const int max_seq = std::min(2*max_tasks_per_batch, (int) llama_n_seq_max(ctx));
|
const int max_seq = std::min(2*max_tasks_per_batch, (int) llama_n_seq_max(ctx));
|
||||||
|
|
||||||
|
@ -1169,7 +1180,7 @@ static void winogrande_score(llama_context * ctx, const common_params & params)
|
||||||
|
|
||||||
std::vector<float> tok_logits(n_vocab);
|
std::vector<float> tok_logits(n_vocab);
|
||||||
// TODO: this could be made smaller; it's currently the worst-case size
|
// TODO: this could be made smaller; it's currently the worst-case size
|
||||||
std::vector<float> batch_logits(n_vocab*n_ctx);
|
std::vector<float> batch_logits(size_t(n_ctx)*n_vocab);
|
||||||
|
|
||||||
std::vector<std::pair<size_t, llama_token>> eval_pairs;
|
std::vector<std::pair<size_t, llama_token>> eval_pairs;
|
||||||
std::vector<float> eval_results;
|
std::vector<float> eval_results;
|
||||||
|
@ -1509,17 +1520,18 @@ static void multiple_choice_score(llama_context * ctx, const common_params & par
|
||||||
|
|
||||||
LOG("\ntask\tacc_norm\n");
|
LOG("\ntask\tacc_norm\n");
|
||||||
|
|
||||||
const int n_vocab = llama_n_vocab(llama_get_model(ctx));
|
|
||||||
const int n_ctx = llama_n_ctx(ctx);
|
const int n_ctx = llama_n_ctx(ctx);
|
||||||
const int n_batch = params.n_batch;
|
const int n_batch = params.n_batch;
|
||||||
|
|
||||||
|
const int n_vocab = llama_n_vocab(llama_get_model(ctx));
|
||||||
|
|
||||||
const int max_tasks_per_batch = 32;
|
const int max_tasks_per_batch = 32;
|
||||||
const int max_seq = std::min(4*max_tasks_per_batch, (int) llama_n_seq_max(ctx));
|
const int max_seq = std::min(4*max_tasks_per_batch, (int) llama_n_seq_max(ctx));
|
||||||
|
|
||||||
llama_batch batch = llama_batch_init(n_ctx, 0, max_seq);
|
llama_batch batch = llama_batch_init(n_ctx, 0, max_seq);
|
||||||
|
|
||||||
std::vector<float> tok_logits(n_vocab);
|
std::vector<float> tok_logits(n_vocab);
|
||||||
std::vector<float> batch_logits(n_vocab*n_ctx);
|
std::vector<float> batch_logits(size_t(n_ctx)*n_vocab);
|
||||||
|
|
||||||
std::vector<std::pair<size_t, llama_token>> eval_pairs;
|
std::vector<std::pair<size_t, llama_token>> eval_pairs;
|
||||||
std::vector<float> eval_results;
|
std::vector<float> eval_results;
|
||||||
|
@ -1627,7 +1639,7 @@ static void multiple_choice_score(llama_context * ctx, const common_params & par
|
||||||
//LOG("\n common_prefix: %zu\n", cur_task.common_prefix);
|
//LOG("\n common_prefix: %zu\n", cur_task.common_prefix);
|
||||||
|
|
||||||
// get the logits of the last token of the common prefix
|
// get the logits of the last token of the common prefix
|
||||||
std::memcpy(tok_logits.data(), batch_logits.data() + n_vocab*cur_task.i_logits, n_vocab*sizeof(float));
|
std::memcpy(tok_logits.data(), batch_logits.data() + cur_task.i_logits*n_vocab, n_vocab*sizeof(float));
|
||||||
|
|
||||||
const auto first_probs = softmax(tok_logits);
|
const auto first_probs = softmax(tok_logits);
|
||||||
|
|
||||||
|
@ -1709,7 +1721,8 @@ static void kl_divergence(llama_context * ctx, const common_params & params) {
|
||||||
__func__, params.logits_file.c_str(), n_ctx, params.n_ctx);
|
__func__, params.logits_file.c_str(), n_ctx, params.n_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
int n_vocab, n_chunk;
|
int n_vocab;
|
||||||
|
int n_chunk;
|
||||||
in.read((char *)&n_vocab, sizeof(n_vocab));
|
in.read((char *)&n_vocab, sizeof(n_vocab));
|
||||||
in.read((char *)&n_chunk, sizeof(n_chunk));
|
in.read((char *)&n_chunk, sizeof(n_chunk));
|
||||||
if (in.fail()) {
|
if (in.fail()) {
|
||||||
|
@ -1720,7 +1733,7 @@ static void kl_divergence(llama_context * ctx, const common_params & params) {
|
||||||
LOG_ERR("%s: inconsistent vocabulary (%d vs %d)\n", __func__, n_vocab, llama_n_vocab(llama_get_model(ctx)));
|
LOG_ERR("%s: inconsistent vocabulary (%d vs %d)\n", __func__, n_vocab, llama_n_vocab(llama_get_model(ctx)));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<llama_token> tokens(n_ctx * n_chunk);
|
std::vector<llama_token> tokens(size_t(n_ctx) * n_chunk);
|
||||||
if (in.read((char *)tokens.data(), tokens.size()*sizeof(tokens[0])).fail()) {
|
if (in.read((char *)tokens.data(), tokens.size()*sizeof(tokens[0])).fail()) {
|
||||||
LOG_ERR("%s: failed reading evaluation tokens from %s\n", __func__, params.logits_file.c_str());
|
LOG_ERR("%s: failed reading evaluation tokens from %s\n", __func__, params.logits_file.c_str());
|
||||||
return;
|
return;
|
||||||
|
@ -1737,7 +1750,7 @@ static void kl_divergence(llama_context * ctx, const common_params & params) {
|
||||||
std::vector<float> p_diff_values(size_t(n_ctx - 1 - n_ctx/2)*n_chunk);
|
std::vector<float> p_diff_values(size_t(n_ctx - 1 - n_ctx/2)*n_chunk);
|
||||||
std::vector<float> logits;
|
std::vector<float> logits;
|
||||||
if (num_batches > 1) {
|
if (num_batches > 1) {
|
||||||
logits.reserve(n_ctx * n_vocab);
|
logits.reserve(size_t(n_ctx) * n_vocab);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::thread> workers(std::thread::hardware_concurrency() - 1);
|
std::vector<std::thread> workers(std::thread::hardware_concurrency() - 1);
|
||||||
|
@ -1801,7 +1814,7 @@ static void kl_divergence(llama_context * ctx, const common_params & params) {
|
||||||
|
|
||||||
if (num_batches > 1) {
|
if (num_batches > 1) {
|
||||||
const auto * batch_logits = llama_get_logits(ctx);
|
const auto * batch_logits = llama_get_logits(ctx);
|
||||||
logits.insert(logits.end(), batch_logits, batch_logits + batch_size * n_vocab);
|
logits.insert(logits.end(), batch_logits, batch_logits + size_t(batch_size) * n_vocab);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1822,7 +1835,7 @@ static void kl_divergence(llama_context * ctx, const common_params & params) {
|
||||||
|
|
||||||
const int first = n_ctx/2;
|
const int first = n_ctx/2;
|
||||||
const float * all_logits = num_batches > 1 ? logits.data() : llama_get_logits(ctx);
|
const float * all_logits = num_batches > 1 ? logits.data() : llama_get_logits(ctx);
|
||||||
process_logits(n_vocab, all_logits + first*n_vocab, tokens.data() + start + first, n_ctx - 1 - first,
|
process_logits(n_vocab, all_logits + size_t(first)*n_vocab, tokens.data() + start + first, n_ctx - 1 - first,
|
||||||
workers, log_probs_uint16, kld, kld_ptr, p_diff_ptr);
|
workers, log_probs_uint16, kld, kld_ptr, p_diff_ptr);
|
||||||
p_diff_ptr += n_ctx - 1 - first;
|
p_diff_ptr += n_ctx - 1 - first;
|
||||||
kld_ptr += n_ctx - 1 - first;
|
kld_ptr += n_ctx - 1 - first;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
set(TARGET llama-simple)
|
set(TARGET llama-simple)
|
||||||
add_executable(${TARGET} simple.cpp)
|
add_executable(${TARGET} simple.cpp)
|
||||||
install(TARGETS ${TARGET} RUNTIME)
|
install(TARGETS ${TARGET} RUNTIME)
|
||||||
target_link_libraries(${TARGET} PRIVATE common llama ${CMAKE_THREAD_LIBS_INIT})
|
target_link_libraries(${TARGET} PRIVATE llama ${CMAKE_THREAD_LIBS_INIT})
|
||||||
target_compile_features(${TARGET} PRIVATE cxx_std_11)
|
target_compile_features(${TARGET} PRIVATE cxx_std_11)
|
||||||
|
|
|
@ -1,50 +1,112 @@
|
||||||
#include "arg.h"
|
|
||||||
#include "common.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include "llama.h"
|
#include "llama.h"
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
static void print_usage(int, char ** argv) {
|
static void print_usage(int, char ** argv) {
|
||||||
LOG("\nexample usage:\n");
|
printf("\nexample usage:\n");
|
||||||
LOG("\n %s -m model.gguf -p \"Hello my name is\" -n 32\n", argv[0]);
|
printf("\n %s -m model.gguf [-n n_predict] [-ngl n_gpu_layers] [prompt]\n", argv[0]);
|
||||||
LOG("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char ** argv) {
|
int main(int argc, char ** argv) {
|
||||||
common_params params;
|
// path to the model gguf file
|
||||||
|
std::string model_path;
|
||||||
|
// prompt to generate text from
|
||||||
|
std::string prompt = "Hello my name is";
|
||||||
|
// number of layers to offload to the GPU
|
||||||
|
int ngl = 99;
|
||||||
|
// number of tokens to predict
|
||||||
|
int n_predict = 32;
|
||||||
|
|
||||||
params.prompt = "Hello my name is";
|
// parse command line arguments
|
||||||
params.n_predict = 32;
|
|
||||||
|
|
||||||
if (!common_params_parse(argc, argv, params, LLAMA_EXAMPLE_COMMON, print_usage)) {
|
{
|
||||||
return 1;
|
int i = 1;
|
||||||
|
for (; i < argc; i++) {
|
||||||
|
if (strcmp(argv[i], "-m") == 0) {
|
||||||
|
if (i + 1 < argc) {
|
||||||
|
model_path = argv[++i];
|
||||||
|
} else {
|
||||||
|
print_usage(argc, argv);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else if (strcmp(argv[i], "-n") == 0) {
|
||||||
|
if (i + 1 < argc) {
|
||||||
|
try {
|
||||||
|
n_predict = std::stoi(argv[++i]);
|
||||||
|
} catch (...) {
|
||||||
|
print_usage(argc, argv);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print_usage(argc, argv);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else if (strcmp(argv[i], "-ngl") == 0) {
|
||||||
|
if (i + 1 < argc) {
|
||||||
|
try {
|
||||||
|
ngl = std::stoi(argv[++i]);
|
||||||
|
} catch (...) {
|
||||||
|
print_usage(argc, argv);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print_usage(argc, argv);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// prompt starts here
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (model_path.empty()) {
|
||||||
|
print_usage(argc, argv);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (i < argc) {
|
||||||
|
prompt = argv[i++];
|
||||||
|
for (; i < argc; i++) {
|
||||||
|
prompt += " ";
|
||||||
|
prompt += argv[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
common_init();
|
|
||||||
|
|
||||||
// total length of the sequence including the prompt
|
|
||||||
const int n_predict = params.n_predict;
|
|
||||||
|
|
||||||
// init LLM
|
|
||||||
|
|
||||||
llama_backend_init();
|
|
||||||
llama_numa_init(params.numa);
|
|
||||||
|
|
||||||
// initialize the model
|
// initialize the model
|
||||||
|
|
||||||
llama_model_params model_params = common_model_params_to_llama(params);
|
llama_model_params model_params = llama_model_default_params();
|
||||||
|
model_params.n_gpu_layers = ngl;
|
||||||
|
|
||||||
llama_model * model = llama_load_model_from_file(params.model.c_str(), model_params);
|
llama_model * model = llama_load_model_from_file(model_path.c_str(), model_params);
|
||||||
|
|
||||||
if (model == NULL) {
|
if (model == NULL) {
|
||||||
fprintf(stderr , "%s: error: unable to load model\n" , __func__);
|
fprintf(stderr , "%s: error: unable to load model\n" , __func__);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tokenize the prompt
|
||||||
|
|
||||||
|
// find the number of tokens in the prompt
|
||||||
|
const int n_prompt = -llama_tokenize(model, prompt.c_str(), prompt.size(), NULL, 0, true, true);
|
||||||
|
|
||||||
|
// allocate space for the tokens and tokenize the prompt
|
||||||
|
std::vector<llama_token> prompt_tokens(n_prompt);
|
||||||
|
if (llama_tokenize(model, prompt.c_str(), prompt.size(), prompt_tokens.data(), prompt_tokens.size(), true, true) < 0) {
|
||||||
|
fprintf(stderr, "%s: error: failed to tokenize the prompt\n", __func__);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// initialize the context
|
// initialize the context
|
||||||
|
|
||||||
llama_context_params ctx_params = common_context_params_to_llama(params);
|
llama_context_params ctx_params = llama_context_default_params();
|
||||||
|
// n_ctx is the context size
|
||||||
|
ctx_params.n_ctx = n_prompt + n_predict - 1;
|
||||||
|
// n_batch is the maximum number of tokens that can be processed in a single call to llama_decode
|
||||||
|
ctx_params.n_batch = n_prompt;
|
||||||
|
// enable performance counters
|
||||||
|
ctx_params.no_perf = false;
|
||||||
|
|
||||||
llama_context * ctx = llama_new_context_with_model(model, ctx_params);
|
llama_context * ctx = llama_new_context_with_model(model, ctx_params);
|
||||||
|
|
||||||
|
@ -53,117 +115,87 @@ int main(int argc, char ** argv) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initialize the sampler
|
||||||
|
|
||||||
auto sparams = llama_sampler_chain_default_params();
|
auto sparams = llama_sampler_chain_default_params();
|
||||||
|
|
||||||
sparams.no_perf = false;
|
sparams.no_perf = false;
|
||||||
|
|
||||||
llama_sampler * smpl = llama_sampler_chain_init(sparams);
|
llama_sampler * smpl = llama_sampler_chain_init(sparams);
|
||||||
|
|
||||||
llama_sampler_chain_add(smpl, llama_sampler_init_greedy());
|
llama_sampler_chain_add(smpl, llama_sampler_init_greedy());
|
||||||
|
|
||||||
// tokenize the prompt
|
|
||||||
|
|
||||||
std::vector<llama_token> tokens_list;
|
|
||||||
tokens_list = common_tokenize(ctx, params.prompt, true);
|
|
||||||
|
|
||||||
const int n_ctx = llama_n_ctx(ctx);
|
|
||||||
const int n_kv_req = tokens_list.size() + (n_predict - tokens_list.size());
|
|
||||||
|
|
||||||
LOG("\n");
|
|
||||||
LOG_INF("%s: n_predict = %d, n_ctx = %d, n_kv_req = %d\n", __func__, n_predict, n_ctx, n_kv_req);
|
|
||||||
|
|
||||||
// make sure the KV cache is big enough to hold all the prompt and generated tokens
|
|
||||||
if (n_kv_req > n_ctx) {
|
|
||||||
LOG_ERR("%s: error: n_kv_req > n_ctx, the required KV cache size is not big enough\n", __func__);
|
|
||||||
LOG_ERR("%s: either reduce n_predict or increase n_ctx\n", __func__);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// print the prompt token-by-token
|
// print the prompt token-by-token
|
||||||
|
|
||||||
LOG("\n");
|
for (auto id : prompt_tokens) {
|
||||||
|
char buf[128];
|
||||||
for (auto id : tokens_list) {
|
int n = llama_token_to_piece(model, id, buf, sizeof(buf), 0, true);
|
||||||
LOG("%s", common_token_to_piece(ctx, id).c_str());
|
if (n < 0) {
|
||||||
|
fprintf(stderr, "%s: error: failed to convert token to piece\n", __func__);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
std::string s(buf, n);
|
||||||
|
printf("%s", s.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a llama_batch with size 512
|
// prepare a batch for the prompt
|
||||||
// we use this object to submit token data for decoding
|
|
||||||
|
|
||||||
llama_batch batch = llama_batch_init(512, 0, 1);
|
llama_batch batch = llama_batch_get_one(prompt_tokens.data(), prompt_tokens.size(), 0, 0);
|
||||||
|
|
||||||
// evaluate the initial prompt
|
|
||||||
for (size_t i = 0; i < tokens_list.size(); i++) {
|
|
||||||
common_batch_add(batch, tokens_list[i], i, { 0 }, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// llama_decode will output logits only for the last token of the prompt
|
|
||||||
batch.logits[batch.n_tokens - 1] = true;
|
|
||||||
|
|
||||||
if (llama_decode(ctx, batch) != 0) {
|
|
||||||
LOG("%s: llama_decode() failed\n", __func__);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// main loop
|
// main loop
|
||||||
|
|
||||||
int n_cur = batch.n_tokens;
|
|
||||||
int n_decode = 0;
|
|
||||||
|
|
||||||
const auto t_main_start = ggml_time_us();
|
const auto t_main_start = ggml_time_us();
|
||||||
|
int n_decode = 0;
|
||||||
|
llama_token new_token_id;
|
||||||
|
|
||||||
|
for (int n_pos = 0; n_pos + batch.n_tokens < n_prompt + n_predict; ) {
|
||||||
|
// evaluate the current batch with the transformer model
|
||||||
|
if (llama_decode(ctx, batch)) {
|
||||||
|
fprintf(stderr, "%s : failed to eval, return code %d\n", __func__, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
n_pos += batch.n_tokens;
|
||||||
|
|
||||||
while (n_cur <= n_predict) {
|
|
||||||
// sample the next token
|
// sample the next token
|
||||||
{
|
{
|
||||||
const llama_token new_token_id = llama_sampler_sample(smpl, ctx, -1);
|
new_token_id = llama_sampler_sample(smpl, ctx, -1);
|
||||||
|
|
||||||
// is it an end of generation?
|
// is it an end of generation?
|
||||||
if (llama_token_is_eog(model, new_token_id) || n_cur == n_predict) {
|
if (llama_token_is_eog(model, new_token_id)) {
|
||||||
LOG("\n");
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG("%s", common_token_to_piece(ctx, new_token_id).c_str());
|
char buf[128];
|
||||||
|
int n = llama_token_to_piece(model, new_token_id, buf, sizeof(buf), 0, true);
|
||||||
|
if (n < 0) {
|
||||||
|
fprintf(stderr, "%s: error: failed to convert token to piece\n", __func__);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
std::string s(buf, n);
|
||||||
|
printf("%s", s.c_str());
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
// prepare the next batch
|
// prepare the next batch with the sampled token
|
||||||
common_batch_clear(batch);
|
batch = llama_batch_get_one(&new_token_id, 1, n_pos, 0);
|
||||||
|
|
||||||
// push this new token for next evaluation
|
|
||||||
common_batch_add(batch, new_token_id, n_cur, { 0 }, true);
|
|
||||||
|
|
||||||
n_decode += 1;
|
n_decode += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
n_cur += 1;
|
|
||||||
|
|
||||||
// evaluate the current batch with the transformer model
|
|
||||||
if (llama_decode(ctx, batch)) {
|
|
||||||
LOG_ERR("%s : failed to eval, return code %d\n", __func__, 1);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG("\n");
|
printf("\n");
|
||||||
|
|
||||||
const auto t_main_end = ggml_time_us();
|
const auto t_main_end = ggml_time_us();
|
||||||
|
|
||||||
LOG_INF("%s: decoded %d tokens in %.2f s, speed: %.2f t/s\n",
|
fprintf(stderr, "%s: decoded %d tokens in %.2f s, speed: %.2f t/s\n",
|
||||||
__func__, n_decode, (t_main_end - t_main_start) / 1000000.0f, n_decode / ((t_main_end - t_main_start) / 1000000.0f));
|
__func__, n_decode, (t_main_end - t_main_start) / 1000000.0f, n_decode / ((t_main_end - t_main_start) / 1000000.0f));
|
||||||
|
|
||||||
LOG("\n");
|
fprintf(stderr, "\n");
|
||||||
llama_perf_sampler_print(smpl);
|
llama_perf_sampler_print(smpl);
|
||||||
llama_perf_context_print(ctx);
|
llama_perf_context_print(ctx);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
|
||||||
LOG("\n");
|
|
||||||
|
|
||||||
llama_batch_free(batch);
|
|
||||||
llama_sampler_free(smpl);
|
llama_sampler_free(smpl);
|
||||||
llama_free(ctx);
|
llama_free(ctx);
|
||||||
llama_free_model(model);
|
llama_free_model(model);
|
||||||
|
|
||||||
llama_backend_free();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue