mirror of
https://github.com/ggerganov/llama.cpp.git
synced 2025-01-12 03:31:46 +00:00
llama : context (cont)
ggml-ci
This commit is contained in:
parent
597ae05d9e
commit
e39a9c1007
@ -1,6 +1,7 @@
|
|||||||
#include "llama-context.h"
|
#include "llama-context.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <cmath>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
@ -28,6 +29,439 @@ void llama_set_s_copy(struct llama_context & lctx) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// llama input
|
||||||
|
|
||||||
|
static int32_t llama_relative_position_bucket(llama_pos x, llama_pos y, uint64_t n_buckets, bool bidirectional) {
|
||||||
|
// TODO move to hparams if a T5 variant appears that uses a different value
|
||||||
|
const int64_t max_distance = 128;
|
||||||
|
|
||||||
|
if (bidirectional) {
|
||||||
|
n_buckets >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int64_t max_exact = n_buckets >> 1;
|
||||||
|
|
||||||
|
int32_t relative_position = x - y;
|
||||||
|
int32_t relative_bucket = 0;
|
||||||
|
if (bidirectional) {
|
||||||
|
relative_bucket += (relative_position > 0) * n_buckets;
|
||||||
|
relative_position = abs(relative_position);
|
||||||
|
} else {
|
||||||
|
relative_position = -std::min<int32_t>(relative_position, 0);
|
||||||
|
}
|
||||||
|
int32_t relative_position_if_large = floorf(max_exact + logf(1.0 * relative_position / max_exact) * (n_buckets - max_exact) / log(1.0 * max_distance / max_exact));
|
||||||
|
relative_position_if_large = std::min<int32_t>(relative_position_if_large, n_buckets - 1);
|
||||||
|
relative_bucket += (relative_position < max_exact ? relative_position : relative_position_if_large);
|
||||||
|
return relative_bucket;
|
||||||
|
}
|
||||||
|
|
||||||
|
void llama_set_inputs(llama_context & lctx, const llama_ubatch & ubatch) {
|
||||||
|
//
|
||||||
|
// set input data
|
||||||
|
//
|
||||||
|
|
||||||
|
const auto & hparams = lctx.model.hparams;
|
||||||
|
const auto & cparams = lctx.cparams;
|
||||||
|
const auto & kv_self = lctx.kv_self;
|
||||||
|
|
||||||
|
if (ubatch.token) {
|
||||||
|
const int64_t n_tokens = ubatch.n_tokens;
|
||||||
|
|
||||||
|
ggml_backend_tensor_set(lctx.inp_tokens, ubatch.token, 0, n_tokens*ggml_element_size(lctx.inp_tokens));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ubatch.embd) {
|
||||||
|
const int64_t n_embd = hparams.n_embd;
|
||||||
|
const int64_t n_tokens = ubatch.n_tokens;
|
||||||
|
|
||||||
|
ggml_backend_tensor_set(lctx.inp_embd, ubatch.embd, 0, n_tokens*n_embd*ggml_element_size(lctx.inp_embd));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ubatch.pos && lctx.inp_pos) {
|
||||||
|
const int64_t n_tokens = ubatch.n_tokens;
|
||||||
|
auto n_pos = lctx.n_pos_per_token;
|
||||||
|
ggml_backend_tensor_set(lctx.inp_pos, ubatch.pos, 0, n_tokens*n_pos*ggml_element_size(lctx.inp_pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hparams.causal_attn || cparams.pooling_type == LLAMA_POOLING_TYPE_NONE) {
|
||||||
|
//GGML_ASSERT(lctx.inp_out_ids && "every model that can must skip unused outputs");
|
||||||
|
|
||||||
|
if (!lctx.inp_out_ids) {
|
||||||
|
LLAMA_LOG_WARN("%s: 'lctx.inp_out_ids' is not created\n", __func__);
|
||||||
|
} else {
|
||||||
|
const int64_t n_tokens = ubatch.n_tokens;
|
||||||
|
|
||||||
|
GGML_ASSERT(ggml_backend_buffer_is_host(lctx.inp_out_ids->buffer));
|
||||||
|
int32_t * data = (int32_t *) lctx.inp_out_ids->data;
|
||||||
|
|
||||||
|
if (lctx.n_outputs == n_tokens) {
|
||||||
|
for (int i = 0; i < n_tokens; ++i) {
|
||||||
|
data[i] = i;
|
||||||
|
}
|
||||||
|
} else if (ubatch.output) {
|
||||||
|
int32_t n_outputs = 0;
|
||||||
|
for (int i = 0; i < n_tokens; ++i) {
|
||||||
|
if (ubatch.output[i]) {
|
||||||
|
data[n_outputs++] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// the graph needs to have been passed the correct number of outputs
|
||||||
|
GGML_ASSERT(lctx.n_outputs == n_outputs);
|
||||||
|
} else if (lctx.n_outputs == 1) {
|
||||||
|
// only keep last output
|
||||||
|
data[0] = n_tokens - 1;
|
||||||
|
} else {
|
||||||
|
GGML_ASSERT(lctx.n_outputs == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GGML_ASSERT(
|
||||||
|
// (!a || b) is a logical implication (a -> b)
|
||||||
|
// !hparams.causal_attn -> !cparams.causal_attn
|
||||||
|
(hparams.causal_attn || !cparams.causal_attn) &&
|
||||||
|
"causal attention is not supported by this model"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (lctx.inp_KQ_mask || lctx.inp_KQ_mask_swa) {
|
||||||
|
// NOTE: hparams.causal_attn indicates the model is capable of generation and uses the kv cache.
|
||||||
|
if (cparams.causal_attn && !lctx.is_encoding) {
|
||||||
|
const int64_t n_kv = kv_self.n;
|
||||||
|
const int64_t n_tokens = ubatch.n_tokens;
|
||||||
|
const int64_t n_seq_tokens = ubatch.n_seq_tokens;
|
||||||
|
const int64_t n_seqs = ubatch.n_seqs;
|
||||||
|
|
||||||
|
|
||||||
|
float * data = nullptr;
|
||||||
|
float * data_swa = nullptr;
|
||||||
|
|
||||||
|
if (lctx.inp_KQ_mask) {
|
||||||
|
GGML_ASSERT(ggml_backend_buffer_is_host(lctx.inp_KQ_mask->buffer));
|
||||||
|
data = (float *) lctx.inp_KQ_mask->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lctx.inp_KQ_mask_swa) {
|
||||||
|
GGML_ASSERT(ggml_backend_buffer_is_host(lctx.inp_KQ_mask_swa->buffer));
|
||||||
|
data_swa = (float *) lctx.inp_KQ_mask_swa->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For causal attention, use only the previous KV cells
|
||||||
|
// of the correct sequence for each token of the ubatch.
|
||||||
|
// It's assumed that if a token in the batch has multiple sequences, they are equivalent.
|
||||||
|
for (int h = 0; h < 1; ++h) {
|
||||||
|
for (int s = 0; s < n_seqs; ++s) {
|
||||||
|
const llama_seq_id seq_id = ubatch.seq_id[s][0];
|
||||||
|
|
||||||
|
for (int j = 0; j < n_seq_tokens; ++j) {
|
||||||
|
const llama_pos pos = ubatch.pos[s*n_seq_tokens + j];
|
||||||
|
|
||||||
|
for (int i = 0; i < n_kv; ++i) {
|
||||||
|
float f;
|
||||||
|
if (!kv_self.cells[i].has_seq_id(seq_id) || kv_self.cells[i].pos > pos) {
|
||||||
|
f = -INFINITY;
|
||||||
|
} else {
|
||||||
|
if (hparams.use_alibi) {
|
||||||
|
f = -std::abs(kv_self.cells[i].pos - pos);
|
||||||
|
} else {
|
||||||
|
f = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
data[h*(n_kv*n_tokens) + s*(n_kv*n_seq_tokens) + j*n_kv + i] = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// may need to cut off old tokens for sliding window
|
||||||
|
if (data_swa) {
|
||||||
|
if (pos - kv_self.cells[i].pos >= (int32_t)hparams.n_swa) {
|
||||||
|
f = -INFINITY;
|
||||||
|
}
|
||||||
|
data_swa[h*(n_kv*n_tokens) + s*(n_kv*n_seq_tokens) + j*n_kv + i] = f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
for (int i = n_tokens; i < GGML_PAD(n_tokens, GGML_KQ_MASK_PAD); ++i) {
|
||||||
|
for (int j = 0; j < n_kv; ++j) {
|
||||||
|
data[h*(n_kv*n_tokens) + i*n_kv + j] = -INFINITY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data_swa) {
|
||||||
|
for (int i = n_tokens; i < GGML_PAD(n_tokens, GGML_KQ_MASK_PAD); ++i) {
|
||||||
|
for (int j = 0; j < n_kv; ++j) {
|
||||||
|
data_swa[h*(n_kv*n_tokens) + i*n_kv + j] = -INFINITY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const int64_t n_tokens = ubatch.n_tokens;
|
||||||
|
const int64_t n_seq_tokens = ubatch.n_seq_tokens;
|
||||||
|
const int64_t n_seqs = ubatch.n_seqs;
|
||||||
|
// when using kv cache, the mask needs to match the kv cache size
|
||||||
|
const int64_t n_stride = hparams.causal_attn && !lctx.is_encoding ? kv_self.n : n_tokens;
|
||||||
|
|
||||||
|
GGML_ASSERT(ggml_backend_buffer_is_host(lctx.inp_KQ_mask->buffer));
|
||||||
|
|
||||||
|
float * data = (float *) lctx.inp_KQ_mask->data;
|
||||||
|
|
||||||
|
for (int h = 0; h < 1; ++h) {
|
||||||
|
for (int s1 = 0; s1 < n_seqs; ++s1) {
|
||||||
|
const llama_seq_id seq_id = ubatch.seq_id[s1][0];
|
||||||
|
|
||||||
|
for (int j = 0; j < n_seq_tokens; ++j) {
|
||||||
|
const int32_t tj = s1*n_seq_tokens + j;
|
||||||
|
|
||||||
|
for (int s0 = 0; s0 < n_seqs; ++s0) {
|
||||||
|
for (int i = 0; i < n_seq_tokens; ++i) {
|
||||||
|
const int32_t ti = s0*n_seq_tokens + i;
|
||||||
|
float f = -INFINITY;
|
||||||
|
|
||||||
|
for (int s = 0; s < ubatch.n_seq_id[s0]; ++s) {
|
||||||
|
if (ubatch.seq_id[s0][s] == seq_id) {
|
||||||
|
if (hparams.use_alibi) {
|
||||||
|
f = -std::abs(ubatch.pos[ti] - ubatch.pos[tj]);
|
||||||
|
} else {
|
||||||
|
f = 0.0f;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data[h*(n_tokens*n_tokens) + tj*n_stride + ti] = f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = n_tokens; i < n_stride; ++i) {
|
||||||
|
data[h*(n_tokens*n_tokens) + tj*n_stride + i] = -INFINITY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cparams.embeddings && cparams.pooling_type == LLAMA_POOLING_TYPE_MEAN) {
|
||||||
|
const int64_t n_tokens = ubatch.n_tokens;
|
||||||
|
const int64_t n_seq_tokens = ubatch.n_seq_tokens;
|
||||||
|
const int64_t n_seqs = ubatch.n_seqs;
|
||||||
|
|
||||||
|
GGML_ASSERT(lctx.inp_mean);
|
||||||
|
GGML_ASSERT(ggml_backend_buffer_is_host(lctx.inp_mean->buffer));
|
||||||
|
|
||||||
|
float * data = (float *) lctx.inp_mean->data;
|
||||||
|
memset(lctx.inp_mean->data, 0, n_tokens * n_tokens * ggml_element_size(lctx.inp_mean));
|
||||||
|
|
||||||
|
std::vector<uint64_t> sum(n_tokens, 0);
|
||||||
|
|
||||||
|
for (int s = 0; s < n_seqs; ++s) {
|
||||||
|
const llama_seq_id seq_id = ubatch.seq_id[s][0];
|
||||||
|
|
||||||
|
// TODO: adapt limits to n_seqs when ubatch.equal_seqs is true
|
||||||
|
GGML_ASSERT(seq_id < n_tokens && "seq_id cannot be larger than n_tokens with pooling_type == MEAN");
|
||||||
|
|
||||||
|
sum[seq_id] += ubatch.n_seq_tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<float> div(n_tokens, 0.0f);
|
||||||
|
for (int i = 0; i < n_tokens; ++i) {
|
||||||
|
const uint64_t s = sum[i];
|
||||||
|
if (s > 0) {
|
||||||
|
div[i] = 1.0f/float(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int s = 0; s < n_seqs; ++s) {
|
||||||
|
const llama_seq_id seq_id = ubatch.seq_id[s][0];
|
||||||
|
|
||||||
|
for (int i = 0; i < n_seq_tokens; ++i) {
|
||||||
|
data[seq_id*n_tokens + s*n_seq_tokens + i] = div[seq_id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cparams.embeddings && (
|
||||||
|
cparams.pooling_type == LLAMA_POOLING_TYPE_CLS ||
|
||||||
|
cparams.pooling_type == LLAMA_POOLING_TYPE_RANK)) {
|
||||||
|
const int64_t n_tokens = ubatch.n_tokens;
|
||||||
|
const int64_t n_seq_tokens = ubatch.n_seq_tokens;
|
||||||
|
const int64_t n_seqs = ubatch.n_seqs;
|
||||||
|
|
||||||
|
GGML_ASSERT(lctx.inp_cls);
|
||||||
|
GGML_ASSERT(ggml_backend_buffer_is_host(lctx.inp_cls->buffer));
|
||||||
|
|
||||||
|
uint32_t * data = (uint32_t *) lctx.inp_cls->data;
|
||||||
|
memset(lctx.inp_cls->data, 0, n_tokens * ggml_element_size(lctx.inp_cls));
|
||||||
|
|
||||||
|
for (int s = 0; s < n_seqs; ++s) {
|
||||||
|
const llama_seq_id seq_id = ubatch.seq_id[s][0];
|
||||||
|
|
||||||
|
// TODO: adapt limits to n_seqs when ubatch.equal_seqs is true
|
||||||
|
GGML_ASSERT(seq_id < n_tokens && "seq_id cannot be larger than n_tokens with pooling_type == CLS or RANK");
|
||||||
|
|
||||||
|
for (int i = 0; i < n_seq_tokens; ++i) {
|
||||||
|
const llama_pos pos = ubatch.pos[s*n_seq_tokens + i];
|
||||||
|
|
||||||
|
if (pos == 0) {
|
||||||
|
data[seq_id] = s*n_seq_tokens + i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cparams.embeddings && cparams.pooling_type == LLAMA_POOLING_TYPE_LAST) {
|
||||||
|
const int64_t n_tokens = ubatch.n_tokens;
|
||||||
|
const int64_t n_seq_tokens = ubatch.n_seq_tokens;
|
||||||
|
const int64_t n_seqs = ubatch.n_seqs;
|
||||||
|
|
||||||
|
GGML_ASSERT(lctx.inp_cls);
|
||||||
|
GGML_ASSERT(ggml_backend_buffer_is_host(lctx.inp_cls->buffer));
|
||||||
|
|
||||||
|
uint32_t * data = (uint32_t *) lctx.inp_cls->data;
|
||||||
|
memset(lctx.inp_cls->data, 0, n_tokens * ggml_element_size(lctx.inp_cls));
|
||||||
|
|
||||||
|
std::vector<int> last_pos(n_tokens, -1);
|
||||||
|
std::vector<int> last_row(n_tokens, -1);
|
||||||
|
|
||||||
|
for (int s = 0; s < n_seqs; ++s) {
|
||||||
|
const llama_seq_id seq_id = ubatch.seq_id[s][0];
|
||||||
|
|
||||||
|
// TODO: adapt limits to n_seqs when ubatch.equal_seqs is true
|
||||||
|
GGML_ASSERT(seq_id < n_tokens && "seq_id cannot be larger than n_tokens with pooling_type == LAST");
|
||||||
|
|
||||||
|
for (int i = 0; i < n_seq_tokens; ++i) {
|
||||||
|
const llama_pos pos = ubatch.pos[s*n_seq_tokens + i];
|
||||||
|
|
||||||
|
if (pos >= last_pos[seq_id]) {
|
||||||
|
last_pos[seq_id] = pos;
|
||||||
|
last_row[seq_id] = s*n_seq_tokens + i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < n_tokens; ++i) {
|
||||||
|
if (last_row[i] >= 0) {
|
||||||
|
data[i] = last_row[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kv_self.recurrent) {
|
||||||
|
const int64_t n_kv = kv_self.n;
|
||||||
|
|
||||||
|
if (lctx.inp_s_mask) {
|
||||||
|
GGML_ASSERT(ggml_backend_buffer_is_host(lctx.inp_s_mask->buffer));
|
||||||
|
float * data = (float *) lctx.inp_s_mask->data;
|
||||||
|
|
||||||
|
// clear unused states
|
||||||
|
for (int i = 0; i < n_kv; ++i) {
|
||||||
|
const uint32_t cell_id = i + kv_self.head;
|
||||||
|
llama_kv_cell & kv_cell = lctx.kv_self.cells[cell_id];
|
||||||
|
|
||||||
|
data[i] = (float) (kv_cell.src >= 0);
|
||||||
|
|
||||||
|
// only clear once
|
||||||
|
if (kv_cell.src < 0) {
|
||||||
|
kv_cell.src = cell_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lctx.inp_s_copy) {
|
||||||
|
GGML_ASSERT(ggml_backend_buffer_is_host(lctx.inp_s_copy->buffer));
|
||||||
|
int32_t * data = (int32_t *) lctx.inp_s_copy->data;
|
||||||
|
|
||||||
|
// assuming copy destinations ALWAYS happen ONLY on the cells between head and head+n
|
||||||
|
for (uint32_t i = 0; i < n_kv; ++i) {
|
||||||
|
const uint32_t cell_id = i + kv_self.head;
|
||||||
|
llama_kv_cell & kv_cell = lctx.kv_self.cells[cell_id];
|
||||||
|
|
||||||
|
// prevent out-of-bound sources
|
||||||
|
if (kv_cell.src < 0 || (uint32_t) kv_cell.src >= kv_self.size) {
|
||||||
|
kv_cell.src = cell_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
data[i] = kv_cell.src;
|
||||||
|
|
||||||
|
// ensure copy only happens once
|
||||||
|
if (kv_cell.src != (int32_t) cell_id) {
|
||||||
|
kv_cell.src = cell_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lctx.inp_pos_bucket) {
|
||||||
|
const int64_t n_tokens = ubatch.n_tokens;
|
||||||
|
|
||||||
|
GGML_ASSERT(ggml_backend_buffer_is_host(lctx.inp_pos_bucket->buffer));
|
||||||
|
GGML_ASSERT(!ubatch.equal_seqs); // TODO: use ubatch.n_seqs instead of failing
|
||||||
|
|
||||||
|
int32_t * data = (int32_t *) lctx.inp_pos_bucket->data;
|
||||||
|
|
||||||
|
if (!lctx.is_encoding) {
|
||||||
|
const int64_t n_kv = kv_self.n;
|
||||||
|
for (int h = 0; h < 1; ++h) {
|
||||||
|
for (int j = 0; j < n_tokens; ++j) {
|
||||||
|
for (int i = 0; i < n_kv; ++i) {
|
||||||
|
data[h*(n_kv*n_tokens) + j*n_kv + i] = llama_relative_position_bucket(lctx.kv_self.cells[i].pos, ubatch.pos[j], hparams.n_rel_attn_bkts, lctx.is_encoding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int h = 0; h < 1; ++h) {
|
||||||
|
for (int j = 0; j < n_tokens; ++j) {
|
||||||
|
for (int i = 0; i < n_tokens; ++i) {
|
||||||
|
data[h*(n_tokens*n_tokens) + j*n_tokens + i] = llama_relative_position_bucket(ubatch.pos[i], ubatch.pos[j], hparams.n_rel_attn_bkts, lctx.is_encoding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lctx.is_encoding && lctx.inp_embd_enc) {
|
||||||
|
assert(lctx.inp_embd_enc->type == GGML_TYPE_F32);
|
||||||
|
assert((size_t) ggml_nelements(lctx.inp_embd_enc) == lctx.embd_enc.size());
|
||||||
|
|
||||||
|
ggml_backend_tensor_set(lctx.inp_embd_enc, lctx.embd_enc.data(), 0, ggml_nbytes(lctx.inp_embd_enc));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lctx.is_encoding && lctx.inp_KQ_mask_cross) {
|
||||||
|
const int64_t n_output_enc = lctx.embd_enc.size() / hparams.n_embd;
|
||||||
|
const int64_t n_tokens = ubatch.n_tokens;
|
||||||
|
|
||||||
|
GGML_ASSERT(ggml_backend_buffer_is_host(lctx.inp_KQ_mask_cross->buffer));
|
||||||
|
GGML_ASSERT(!ubatch.equal_seqs); // TODO: use ubatch.n_seqs instead of failing
|
||||||
|
|
||||||
|
float * data = (float *) lctx.inp_KQ_mask_cross->data;
|
||||||
|
|
||||||
|
for (int h = 0; h < 1; ++h) {
|
||||||
|
for (int j = 0; j < n_tokens; ++j) {
|
||||||
|
for (int i = 0; i < n_output_enc; ++i) {
|
||||||
|
float f = -INFINITY;
|
||||||
|
for (int s = 0; s < ubatch.n_seq_id[j]; ++s) {
|
||||||
|
const llama_seq_id seq_id = ubatch.seq_id[j][s];
|
||||||
|
if (lctx.seq_ids_enc[i].find(seq_id) != lctx.seq_ids_enc[i].end()) {
|
||||||
|
f = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data[h*(n_output_enc*n_tokens) + j*n_output_enc + i] = f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = n_tokens; i < GGML_PAD(n_tokens, GGML_KQ_MASK_PAD); ++i) {
|
||||||
|
for (int j = 0; j < n_output_enc; ++j) {
|
||||||
|
data[h*(n_output_enc*n_tokens) + i*n_output_enc + j] = -INFINITY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// llama output
|
// llama output
|
||||||
|
|
||||||
size_t llama_output_reserve(struct llama_context & lctx, size_t n_outputs) {
|
size_t llama_output_reserve(struct llama_context & lctx, size_t n_outputs) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "llama-impl.h"
|
#include "llama.h"
|
||||||
#include "llama-batch.h"
|
#include "llama-batch.h"
|
||||||
#include "llama-cparams.h"
|
#include "llama-cparams.h"
|
||||||
#include "llama-model.h"
|
#include "llama-model.h"
|
||||||
@ -114,6 +114,8 @@ void llama_set_k_shift(struct llama_context & lctx);
|
|||||||
|
|
||||||
void llama_set_s_copy(struct llama_context & lctx);
|
void llama_set_s_copy(struct llama_context & lctx);
|
||||||
|
|
||||||
|
void llama_set_inputs(llama_context & lctx, const llama_ubatch & ubatch);
|
||||||
|
|
||||||
// Make sure enough space is available for outputs.
|
// Make sure enough space is available for outputs.
|
||||||
// Returns max number of outputs for which space was reserved.
|
// Returns max number of outputs for which space was reserved.
|
||||||
size_t llama_output_reserve(struct llama_context & lctx, size_t n_outputs);
|
size_t llama_output_reserve(struct llama_context & lctx, size_t n_outputs);
|
||||||
|
431
src/llama.cpp
431
src/llama.cpp
@ -13411,437 +13411,6 @@ static struct ggml_cgraph * llama_build_graph(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t llama_relative_position_bucket(llama_pos x, llama_pos y, uint64_t n_buckets, bool bidirectional) {
|
|
||||||
// TODO move to hparams if a T5 variant appears that uses a different value
|
|
||||||
const int64_t max_distance = 128;
|
|
||||||
|
|
||||||
if (bidirectional) {
|
|
||||||
n_buckets >>= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int64_t max_exact = n_buckets >> 1;
|
|
||||||
|
|
||||||
int32_t relative_position = x - y;
|
|
||||||
int32_t relative_bucket = 0;
|
|
||||||
if (bidirectional) {
|
|
||||||
relative_bucket += (relative_position > 0) * n_buckets;
|
|
||||||
relative_position = abs(relative_position);
|
|
||||||
} else {
|
|
||||||
relative_position = -std::min<int32_t>(relative_position, 0);
|
|
||||||
}
|
|
||||||
int32_t relative_position_if_large = floorf(max_exact + logf(1.0 * relative_position / max_exact) * (n_buckets - max_exact) / log(1.0 * max_distance / max_exact));
|
|
||||||
relative_position_if_large = std::min<int32_t>(relative_position_if_large, n_buckets - 1);
|
|
||||||
relative_bucket += (relative_position < max_exact ? relative_position : relative_position_if_large);
|
|
||||||
return relative_bucket;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void llama_set_inputs(llama_context & lctx, const llama_ubatch & ubatch) {
|
|
||||||
//
|
|
||||||
// set input data
|
|
||||||
//
|
|
||||||
|
|
||||||
const auto & hparams = lctx.model.hparams;
|
|
||||||
const auto & cparams = lctx.cparams;
|
|
||||||
const auto & kv_self = lctx.kv_self;
|
|
||||||
|
|
||||||
if (ubatch.token) {
|
|
||||||
const int64_t n_tokens = ubatch.n_tokens;
|
|
||||||
|
|
||||||
ggml_backend_tensor_set(lctx.inp_tokens, ubatch.token, 0, n_tokens*ggml_element_size(lctx.inp_tokens));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ubatch.embd) {
|
|
||||||
const int64_t n_embd = hparams.n_embd;
|
|
||||||
const int64_t n_tokens = ubatch.n_tokens;
|
|
||||||
|
|
||||||
ggml_backend_tensor_set(lctx.inp_embd, ubatch.embd, 0, n_tokens*n_embd*ggml_element_size(lctx.inp_embd));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ubatch.pos && lctx.inp_pos) {
|
|
||||||
const int64_t n_tokens = ubatch.n_tokens;
|
|
||||||
auto n_pos = lctx.n_pos_per_token;
|
|
||||||
ggml_backend_tensor_set(lctx.inp_pos, ubatch.pos, 0, n_tokens*n_pos*ggml_element_size(lctx.inp_pos));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hparams.causal_attn || cparams.pooling_type == LLAMA_POOLING_TYPE_NONE) {
|
|
||||||
//GGML_ASSERT(lctx.inp_out_ids && "every model that can must skip unused outputs");
|
|
||||||
|
|
||||||
if (!lctx.inp_out_ids) {
|
|
||||||
LLAMA_LOG_WARN("%s: 'lctx.inp_out_ids' is not created\n", __func__);
|
|
||||||
} else {
|
|
||||||
const int64_t n_tokens = ubatch.n_tokens;
|
|
||||||
|
|
||||||
GGML_ASSERT(ggml_backend_buffer_is_host(lctx.inp_out_ids->buffer));
|
|
||||||
int32_t * data = (int32_t *) lctx.inp_out_ids->data;
|
|
||||||
|
|
||||||
if (lctx.n_outputs == n_tokens) {
|
|
||||||
for (int i = 0; i < n_tokens; ++i) {
|
|
||||||
data[i] = i;
|
|
||||||
}
|
|
||||||
} else if (ubatch.output) {
|
|
||||||
int32_t n_outputs = 0;
|
|
||||||
for (int i = 0; i < n_tokens; ++i) {
|
|
||||||
if (ubatch.output[i]) {
|
|
||||||
data[n_outputs++] = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// the graph needs to have been passed the correct number of outputs
|
|
||||||
GGML_ASSERT(lctx.n_outputs == n_outputs);
|
|
||||||
} else if (lctx.n_outputs == 1) {
|
|
||||||
// only keep last output
|
|
||||||
data[0] = n_tokens - 1;
|
|
||||||
} else {
|
|
||||||
GGML_ASSERT(lctx.n_outputs == 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GGML_ASSERT(
|
|
||||||
// (!a || b) is a logical implication (a -> b)
|
|
||||||
// !hparams.causal_attn -> !cparams.causal_attn
|
|
||||||
(hparams.causal_attn || !cparams.causal_attn) &&
|
|
||||||
"causal attention is not supported by this model"
|
|
||||||
);
|
|
||||||
|
|
||||||
if (lctx.inp_KQ_mask || lctx.inp_KQ_mask_swa) {
|
|
||||||
// NOTE: hparams.causal_attn indicates the model is capable of generation and uses the kv cache.
|
|
||||||
if (cparams.causal_attn && !lctx.is_encoding) {
|
|
||||||
const int64_t n_kv = kv_self.n;
|
|
||||||
const int64_t n_tokens = ubatch.n_tokens;
|
|
||||||
const int64_t n_seq_tokens = ubatch.n_seq_tokens;
|
|
||||||
const int64_t n_seqs = ubatch.n_seqs;
|
|
||||||
|
|
||||||
|
|
||||||
float * data = nullptr;
|
|
||||||
float * data_swa = nullptr;
|
|
||||||
|
|
||||||
if (lctx.inp_KQ_mask) {
|
|
||||||
GGML_ASSERT(ggml_backend_buffer_is_host(lctx.inp_KQ_mask->buffer));
|
|
||||||
data = (float *) lctx.inp_KQ_mask->data;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lctx.inp_KQ_mask_swa) {
|
|
||||||
GGML_ASSERT(ggml_backend_buffer_is_host(lctx.inp_KQ_mask_swa->buffer));
|
|
||||||
data_swa = (float *) lctx.inp_KQ_mask_swa->data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// For causal attention, use only the previous KV cells
|
|
||||||
// of the correct sequence for each token of the ubatch.
|
|
||||||
// It's assumed that if a token in the batch has multiple sequences, they are equivalent.
|
|
||||||
for (int h = 0; h < 1; ++h) {
|
|
||||||
for (int s = 0; s < n_seqs; ++s) {
|
|
||||||
const llama_seq_id seq_id = ubatch.seq_id[s][0];
|
|
||||||
|
|
||||||
for (int j = 0; j < n_seq_tokens; ++j) {
|
|
||||||
const llama_pos pos = ubatch.pos[s*n_seq_tokens + j];
|
|
||||||
|
|
||||||
for (int i = 0; i < n_kv; ++i) {
|
|
||||||
float f;
|
|
||||||
if (!kv_self.cells[i].has_seq_id(seq_id) || kv_self.cells[i].pos > pos) {
|
|
||||||
f = -INFINITY;
|
|
||||||
} else {
|
|
||||||
if (hparams.use_alibi) {
|
|
||||||
f = -std::abs(kv_self.cells[i].pos - pos);
|
|
||||||
} else {
|
|
||||||
f = 0.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data) {
|
|
||||||
data[h*(n_kv*n_tokens) + s*(n_kv*n_seq_tokens) + j*n_kv + i] = f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// may need to cut off old tokens for sliding window
|
|
||||||
if (data_swa) {
|
|
||||||
if (pos - kv_self.cells[i].pos >= (int32_t)hparams.n_swa) {
|
|
||||||
f = -INFINITY;
|
|
||||||
}
|
|
||||||
data_swa[h*(n_kv*n_tokens) + s*(n_kv*n_seq_tokens) + j*n_kv + i] = f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data) {
|
|
||||||
for (int i = n_tokens; i < GGML_PAD(n_tokens, GGML_KQ_MASK_PAD); ++i) {
|
|
||||||
for (int j = 0; j < n_kv; ++j) {
|
|
||||||
data[h*(n_kv*n_tokens) + i*n_kv + j] = -INFINITY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data_swa) {
|
|
||||||
for (int i = n_tokens; i < GGML_PAD(n_tokens, GGML_KQ_MASK_PAD); ++i) {
|
|
||||||
for (int j = 0; j < n_kv; ++j) {
|
|
||||||
data_swa[h*(n_kv*n_tokens) + i*n_kv + j] = -INFINITY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const int64_t n_tokens = ubatch.n_tokens;
|
|
||||||
const int64_t n_seq_tokens = ubatch.n_seq_tokens;
|
|
||||||
const int64_t n_seqs = ubatch.n_seqs;
|
|
||||||
// when using kv cache, the mask needs to match the kv cache size
|
|
||||||
const int64_t n_stride = hparams.causal_attn && !lctx.is_encoding ? kv_self.n : n_tokens;
|
|
||||||
|
|
||||||
GGML_ASSERT(ggml_backend_buffer_is_host(lctx.inp_KQ_mask->buffer));
|
|
||||||
|
|
||||||
float * data = (float *) lctx.inp_KQ_mask->data;
|
|
||||||
|
|
||||||
for (int h = 0; h < 1; ++h) {
|
|
||||||
for (int s1 = 0; s1 < n_seqs; ++s1) {
|
|
||||||
const llama_seq_id seq_id = ubatch.seq_id[s1][0];
|
|
||||||
|
|
||||||
for (int j = 0; j < n_seq_tokens; ++j) {
|
|
||||||
const int32_t tj = s1*n_seq_tokens + j;
|
|
||||||
|
|
||||||
for (int s0 = 0; s0 < n_seqs; ++s0) {
|
|
||||||
for (int i = 0; i < n_seq_tokens; ++i) {
|
|
||||||
const int32_t ti = s0*n_seq_tokens + i;
|
|
||||||
float f = -INFINITY;
|
|
||||||
|
|
||||||
for (int s = 0; s < ubatch.n_seq_id[s0]; ++s) {
|
|
||||||
if (ubatch.seq_id[s0][s] == seq_id) {
|
|
||||||
if (hparams.use_alibi) {
|
|
||||||
f = -std::abs(ubatch.pos[ti] - ubatch.pos[tj]);
|
|
||||||
} else {
|
|
||||||
f = 0.0f;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data[h*(n_tokens*n_tokens) + tj*n_stride + ti] = f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = n_tokens; i < n_stride; ++i) {
|
|
||||||
data[h*(n_tokens*n_tokens) + tj*n_stride + i] = -INFINITY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cparams.embeddings && cparams.pooling_type == LLAMA_POOLING_TYPE_MEAN) {
|
|
||||||
const int64_t n_tokens = ubatch.n_tokens;
|
|
||||||
const int64_t n_seq_tokens = ubatch.n_seq_tokens;
|
|
||||||
const int64_t n_seqs = ubatch.n_seqs;
|
|
||||||
|
|
||||||
GGML_ASSERT(lctx.inp_mean);
|
|
||||||
GGML_ASSERT(ggml_backend_buffer_is_host(lctx.inp_mean->buffer));
|
|
||||||
|
|
||||||
float * data = (float *) lctx.inp_mean->data;
|
|
||||||
memset(lctx.inp_mean->data, 0, n_tokens * n_tokens * ggml_element_size(lctx.inp_mean));
|
|
||||||
|
|
||||||
std::vector<uint64_t> sum(n_tokens, 0);
|
|
||||||
|
|
||||||
for (int s = 0; s < n_seqs; ++s) {
|
|
||||||
const llama_seq_id seq_id = ubatch.seq_id[s][0];
|
|
||||||
|
|
||||||
// TODO: adapt limits to n_seqs when ubatch.equal_seqs is true
|
|
||||||
GGML_ASSERT(seq_id < n_tokens && "seq_id cannot be larger than n_tokens with pooling_type == MEAN");
|
|
||||||
|
|
||||||
sum[seq_id] += ubatch.n_seq_tokens;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<float> div(n_tokens, 0.0f);
|
|
||||||
for (int i = 0; i < n_tokens; ++i) {
|
|
||||||
const uint64_t s = sum[i];
|
|
||||||
if (s > 0) {
|
|
||||||
div[i] = 1.0f/float(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int s = 0; s < n_seqs; ++s) {
|
|
||||||
const llama_seq_id seq_id = ubatch.seq_id[s][0];
|
|
||||||
|
|
||||||
for (int i = 0; i < n_seq_tokens; ++i) {
|
|
||||||
data[seq_id*n_tokens + s*n_seq_tokens + i] = div[seq_id];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cparams.embeddings && (
|
|
||||||
cparams.pooling_type == LLAMA_POOLING_TYPE_CLS ||
|
|
||||||
cparams.pooling_type == LLAMA_POOLING_TYPE_RANK)) {
|
|
||||||
const int64_t n_tokens = ubatch.n_tokens;
|
|
||||||
const int64_t n_seq_tokens = ubatch.n_seq_tokens;
|
|
||||||
const int64_t n_seqs = ubatch.n_seqs;
|
|
||||||
|
|
||||||
GGML_ASSERT(lctx.inp_cls);
|
|
||||||
GGML_ASSERT(ggml_backend_buffer_is_host(lctx.inp_cls->buffer));
|
|
||||||
|
|
||||||
uint32_t * data = (uint32_t *) lctx.inp_cls->data;
|
|
||||||
memset(lctx.inp_cls->data, 0, n_tokens * ggml_element_size(lctx.inp_cls));
|
|
||||||
|
|
||||||
for (int s = 0; s < n_seqs; ++s) {
|
|
||||||
const llama_seq_id seq_id = ubatch.seq_id[s][0];
|
|
||||||
|
|
||||||
// TODO: adapt limits to n_seqs when ubatch.equal_seqs is true
|
|
||||||
GGML_ASSERT(seq_id < n_tokens && "seq_id cannot be larger than n_tokens with pooling_type == CLS or RANK");
|
|
||||||
|
|
||||||
for (int i = 0; i < n_seq_tokens; ++i) {
|
|
||||||
const llama_pos pos = ubatch.pos[s*n_seq_tokens + i];
|
|
||||||
|
|
||||||
if (pos == 0) {
|
|
||||||
data[seq_id] = s*n_seq_tokens + i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cparams.embeddings && cparams.pooling_type == LLAMA_POOLING_TYPE_LAST) {
|
|
||||||
const int64_t n_tokens = ubatch.n_tokens;
|
|
||||||
const int64_t n_seq_tokens = ubatch.n_seq_tokens;
|
|
||||||
const int64_t n_seqs = ubatch.n_seqs;
|
|
||||||
|
|
||||||
GGML_ASSERT(lctx.inp_cls);
|
|
||||||
GGML_ASSERT(ggml_backend_buffer_is_host(lctx.inp_cls->buffer));
|
|
||||||
|
|
||||||
uint32_t * data = (uint32_t *) lctx.inp_cls->data;
|
|
||||||
memset(lctx.inp_cls->data, 0, n_tokens * ggml_element_size(lctx.inp_cls));
|
|
||||||
|
|
||||||
std::vector<int> last_pos(n_tokens, -1);
|
|
||||||
std::vector<int> last_row(n_tokens, -1);
|
|
||||||
|
|
||||||
for (int s = 0; s < n_seqs; ++s) {
|
|
||||||
const llama_seq_id seq_id = ubatch.seq_id[s][0];
|
|
||||||
|
|
||||||
// TODO: adapt limits to n_seqs when ubatch.equal_seqs is true
|
|
||||||
GGML_ASSERT(seq_id < n_tokens && "seq_id cannot be larger than n_tokens with pooling_type == LAST");
|
|
||||||
|
|
||||||
for (int i = 0; i < n_seq_tokens; ++i) {
|
|
||||||
const llama_pos pos = ubatch.pos[s*n_seq_tokens + i];
|
|
||||||
|
|
||||||
if (pos >= last_pos[seq_id]) {
|
|
||||||
last_pos[seq_id] = pos;
|
|
||||||
last_row[seq_id] = s*n_seq_tokens + i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < n_tokens; ++i) {
|
|
||||||
if (last_row[i] >= 0) {
|
|
||||||
data[i] = last_row[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (kv_self.recurrent) {
|
|
||||||
const int64_t n_kv = kv_self.n;
|
|
||||||
|
|
||||||
if (lctx.inp_s_mask) {
|
|
||||||
GGML_ASSERT(ggml_backend_buffer_is_host(lctx.inp_s_mask->buffer));
|
|
||||||
float * data = (float *) lctx.inp_s_mask->data;
|
|
||||||
|
|
||||||
// clear unused states
|
|
||||||
for (int i = 0; i < n_kv; ++i) {
|
|
||||||
const uint32_t cell_id = i + kv_self.head;
|
|
||||||
llama_kv_cell & kv_cell = lctx.kv_self.cells[cell_id];
|
|
||||||
|
|
||||||
data[i] = (float) (kv_cell.src >= 0);
|
|
||||||
|
|
||||||
// only clear once
|
|
||||||
if (kv_cell.src < 0) {
|
|
||||||
kv_cell.src = cell_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lctx.inp_s_copy) {
|
|
||||||
GGML_ASSERT(ggml_backend_buffer_is_host(lctx.inp_s_copy->buffer));
|
|
||||||
int32_t * data = (int32_t *) lctx.inp_s_copy->data;
|
|
||||||
|
|
||||||
// assuming copy destinations ALWAYS happen ONLY on the cells between head and head+n
|
|
||||||
for (uint32_t i = 0; i < n_kv; ++i) {
|
|
||||||
const uint32_t cell_id = i + kv_self.head;
|
|
||||||
llama_kv_cell & kv_cell = lctx.kv_self.cells[cell_id];
|
|
||||||
|
|
||||||
// prevent out-of-bound sources
|
|
||||||
if (kv_cell.src < 0 || (uint32_t) kv_cell.src >= kv_self.size) {
|
|
||||||
kv_cell.src = cell_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
data[i] = kv_cell.src;
|
|
||||||
|
|
||||||
// ensure copy only happens once
|
|
||||||
if (kv_cell.src != (int32_t) cell_id) {
|
|
||||||
kv_cell.src = cell_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lctx.inp_pos_bucket) {
|
|
||||||
const int64_t n_tokens = ubatch.n_tokens;
|
|
||||||
|
|
||||||
GGML_ASSERT(ggml_backend_buffer_is_host(lctx.inp_pos_bucket->buffer));
|
|
||||||
GGML_ASSERT(!ubatch.equal_seqs); // TODO: use ubatch.n_seqs instead of failing
|
|
||||||
|
|
||||||
int32_t * data = (int32_t *) lctx.inp_pos_bucket->data;
|
|
||||||
|
|
||||||
if (!lctx.is_encoding) {
|
|
||||||
const int64_t n_kv = kv_self.n;
|
|
||||||
for (int h = 0; h < 1; ++h) {
|
|
||||||
for (int j = 0; j < n_tokens; ++j) {
|
|
||||||
for (int i = 0; i < n_kv; ++i) {
|
|
||||||
data[h*(n_kv*n_tokens) + j*n_kv + i] = llama_relative_position_bucket(lctx.kv_self.cells[i].pos, ubatch.pos[j], hparams.n_rel_attn_bkts, lctx.is_encoding);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (int h = 0; h < 1; ++h) {
|
|
||||||
for (int j = 0; j < n_tokens; ++j) {
|
|
||||||
for (int i = 0; i < n_tokens; ++i) {
|
|
||||||
data[h*(n_tokens*n_tokens) + j*n_tokens + i] = llama_relative_position_bucket(ubatch.pos[i], ubatch.pos[j], hparams.n_rel_attn_bkts, lctx.is_encoding);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!lctx.is_encoding && lctx.inp_embd_enc) {
|
|
||||||
assert(lctx.inp_embd_enc->type == GGML_TYPE_F32);
|
|
||||||
assert((size_t) ggml_nelements(lctx.inp_embd_enc) == lctx.embd_enc.size());
|
|
||||||
|
|
||||||
ggml_backend_tensor_set(lctx.inp_embd_enc, lctx.embd_enc.data(), 0, ggml_nbytes(lctx.inp_embd_enc));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!lctx.is_encoding && lctx.inp_KQ_mask_cross) {
|
|
||||||
const int64_t n_output_enc = lctx.embd_enc.size() / hparams.n_embd;
|
|
||||||
const int64_t n_tokens = ubatch.n_tokens;
|
|
||||||
|
|
||||||
GGML_ASSERT(ggml_backend_buffer_is_host(lctx.inp_KQ_mask_cross->buffer));
|
|
||||||
GGML_ASSERT(!ubatch.equal_seqs); // TODO: use ubatch.n_seqs instead of failing
|
|
||||||
|
|
||||||
float * data = (float *) lctx.inp_KQ_mask_cross->data;
|
|
||||||
|
|
||||||
for (int h = 0; h < 1; ++h) {
|
|
||||||
for (int j = 0; j < n_tokens; ++j) {
|
|
||||||
for (int i = 0; i < n_output_enc; ++i) {
|
|
||||||
float f = -INFINITY;
|
|
||||||
for (int s = 0; s < ubatch.n_seq_id[j]; ++s) {
|
|
||||||
const llama_seq_id seq_id = ubatch.seq_id[j][s];
|
|
||||||
if (lctx.seq_ids_enc[i].find(seq_id) != lctx.seq_ids_enc[i].end()) {
|
|
||||||
f = 0.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
data[h*(n_output_enc*n_tokens) + j*n_output_enc + i] = f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = n_tokens; i < GGML_PAD(n_tokens, GGML_KQ_MASK_PAD); ++i) {
|
|
||||||
for (int j = 0; j < n_output_enc; ++j) {
|
|
||||||
data[h*(n_output_enc*n_tokens) + i*n_output_enc + j] = -INFINITY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns the result of ggml_backend_sched_graph_compute_async execution
|
// returns the result of ggml_backend_sched_graph_compute_async execution
|
||||||
static enum ggml_status llama_graph_compute(
|
static enum ggml_status llama_graph_compute(
|
||||||
llama_context & lctx,
|
llama_context & lctx,
|
||||||
|
Loading…
Reference in New Issue
Block a user