DeepSeek-V3 Technical Report Статья: https://arxiv.org/abs/2412.19437 Репа: https://github.com/deepseek-ai/DeepSeek-V3 Предыдущий пост про DeepSeek был попсовый (https://t.me/gonzo_ML/3239), сегодня хочется пройтись по некоторым техническим решениям в DeepSeek, которые мы тут раньше не обсуждали. В-нулевых, что важно знать про DeepSeek-V3 — это всё ещё относительно классический трансформер декодер (но с MoE, https://t.me/gonzo_ML/472). DeepSeek-V3 содержит 671B параметров, из которых активны 37B для каждого токена. 61 трансформерный слой, d_h = 7168. В работе есть несколько интересных решений, которые хочется отметить для истории. Для начала пара вещей, проверенных в DeepSeek-V2 (https://arxiv.org/abs/2405.04434). ❇️ Во-первых, Multi-head Latent Attention (MLA). Что это такое? В классическом __Multi-Head Attention (MHA)__ эмбеддинги входных токенов h_t проецируются в векторы query, key, value q_t, k_t, v_t через незавимимые матрицы проекций W^q, W^k, W^v и затем нарезаются на векторы для отдельных голов внимания. После работы self-attention (тот самый softmax(QK/sqrt(d))*V ), получаем o_t для отдельных голов, конкатенируем и далее через матрицу W^o генерим выход слоя. MLA делает низкоранговую компрессию для key и values, где h_t сначала проецируется в низкоранговый латентный вектор c_t, а потом из этого вектора через отдельные матрицы W^uk, W^uv, разворачивается в k_t, v_t. Размер латентного вектора, d_c, сильно меньше, чем итоговая размерность с учётом всех голов (d_h*n_h). На инференсе это сокращает размер необходимого KV-кеша, потому что надо кешировать только низкоразмерные c_t, а не полноразмерные k_t, v_t как раньше. Более того, матрицы проекций из c_t в ключи и значения можно вообще убрать, матрицу для k_t (W^uk) можно инкорпорировать внутрь матрицы для получения q_t (W^q), а матрицу для v_t (W^uv) внутрь выходной матрицы W^o. На самом деле и для q_t тоже делается низкоранговая компрессия в свой вектор c_t, это не влияет на KV-кеш, но помогает уменьшить объём памяти для активаций при обучении. Была проблема с тем, что позиционные эмбеддинги RoPE несовместимы с низкоранговой компрессией KV, для решения этой проблемы предложили decoupled RoPE strategy с дополнительными многоголовыми q^R и шареным k^R со своей размерностью d^R_h на голову. Итоговые вектора для Q и K являются конкатенацией векторов полученных из соответствующего низкорангового вектора c_t и вектора для RoPE (q^R, k^R). Посмотрите на формулы (раздел 2.1.2), там понятнее, чем текстом. В DeepSeek-V2, размерность латентного вектора d_c была установлена в 4d_h (суммарная размерность четырёх голов), а размерность для RoPE d^R_h в d_h/2 (полголовы). В MLA DeepSeek-V3 128 голов внимания, каждая размерности 128. Размерность d_c равна 512. Помните, что это не единственный способ оптимизации внимания при ускорении генерации и от классического MHA уже много где ушли в __Multi-Query Attention (MQA)__ имени Ноама Шазира (https://arxiv.org/abs/1911.02150), где K и V шарятся между всеми головами внимания (что сильно ускоряет инференс и слегка ухудшает качество), и __Grouped-Query Attention (GQA)__ тоже от Гугла (https://arxiv.org/abs/2305.13245), которое было срединным путём между MHA и MQA, и где количество key-value голов было больше одной, но меньше полного набора как у query — здесь по одной key-value голове на группу query голов — и качество можно приближать к оригинальному MHA. MLA хорошо экономит кеш, сравним с GQA с 2.25 групп, при этом перформанс даже выше MHA. В общем выглядит так, что MLA должен теперь доминировать везде. Не знаю, есть ли что-то лучше из опубликованного?