Ollama API在一段时间后,较大的模型推理会出现挂起现象,

gjmwrych  于 2个月前  发布在  其他
关注(0)|答案(7)|浏览(35)

问题是什么?

在运行占用大部分显存的模型时,通过API进行推理(包括OpenAI/chat/completions)运行正常,直到出现一堆关于"slot context shift"的日志消息后,它就停止响应了。

你期望看到什么?

API能够正常响应。

重现步骤

加载一个大型模型,如nous mixtral dpo,并填充大部分显存,向模型发起几次API调用,最终它会停止响应。

是否最近有更改引入了这个问题?

这种情况已经持续一段时间了,我在使用原生Windows版本后开始注意到更多。

OS

Windows

架构

amd64

平台

  • 无响应*

Ollama版本

0.1.30

GPU

Nvidia

GPU信息

RTX 4090

CPU

Intel

其他软件

  • 无响应*
jdzmm42g

jdzmm42g1#

我遇到了相同的问题。当消息非常长时,模型会永远挂起。从观察流响应行为来看,似乎在输出几个标记后就停止输出标记。

b09cbbtk

b09cbbtk3#

这可能是一个有趣的现象,我看到在温度为0和相对较短的提示下也发生了这种情况,重新运行时是正常的。也许在请求之间有一些缓存导致了这个问题?我在JSON模式和OpenAI端点中注意到了这一点,但它似乎并不仅限于这些。

brvekthn

brvekthn4#

作为对此的更新,llama.cpp似乎没有问题,所以这可能是与ollama特定的问题。

mo49yndu

mo49yndu5#

我认为这可能是由于KV缓存不匹配导致的。我仍在努力找到最终原因。

在上下文切换之前,许多先前的嵌入都存储在KV缓存中。似乎在上下文切换之后,许多迭代中KV缓存都未命中。因此,每次都需要重新计算嵌入,这花费了很多时间。顺便说一下,这是由Felix Wang发现的。

bpsygsoo

bpsygsoo6#

遇到这个问题时,cache_tokens的大小达到了上下文大小。
ext_server/server.cpp中,第1608行:

llama_kv_cache_seq_rm (ctx, slot.id, n_keep , n_keep + n_discard);
llama_kv_cache_seq_add(ctx, slot.id, n_keep + n_discard, system_tokens.size() + slot.n_past, -n_discard);

for (size_t i = n_keep + n_discard; i < slot.cache_tokens.size(); i++)
{
    slot.cache_tokens[i - n_discard] = slot.cache_tokens[i];
}

slot.cache_tokens.resize(slot.cache_tokens.size() - n_discard);

slot.n_past -= n_discard;

此插槽的cache_tokens已更新。然而,在第1775行:

slot.n_past = common_part(slot.cache_tokens, prompt_tokens);

服务器似乎试图在cache_tokensprompt_tokens之间找到公共部分。prompt_tokens记住整个历史,但在上下文切换期间,cache_tokens被截断。因此,你可以想象大多数情况下公共部分的长度为1。
结果是,在第1831行:

int p0 = (int) system_tokens.size() + slot.n_past;
LOG_INFO("kv cache rm [p0, end)", {
    { "slot_id", slot.id },
    { "task_id", slot.task_id },
    { "p0",      p0 }
});
llama_kv_cache_seq_rm(ctx, slot.id, p0, -1);

p0将为1,因此几乎所有的kv缓存序列都将被删除。从现在开始,kv缓存将无法工作,因为处理过的令牌将填充kv缓存,然后触发上下文切换,切断cache_tokens。然后由于cache_tokens和prompt_tokens之间的不匹配,kv缓存将被重置。
希望这能帮到你😊。

6kkfgxo0

6kkfgxo07#

我也看到了这个问题,我认为是在0.1.29升级到0.1.31之后出现的,但不确定。在一段时间内(一两天)运行正常,然后会出现无限循环的

{
  "function": "update_slots",
  "level": "INFO",
  "line": 1601,
  "msg": "slot context shift",
  "n_cache_tokens": 16384,
  "n_ctx": 16384,
  "n_discard": 8191,
  "n_keep": 1,
  "n_left": 16382,
  "n_past": 16383,
  "n_system_tokens": 0,
  "slot_id": 0,
  "task_id": 8,
  "tid": "124603937681408",
  "timestamp": 1713703989
}

,其中"task_id"是相同的。消息大约每隔3分钟出现一次。重启服务器似乎是唯一的解决方法。

相关问题