Пример подхода RWKV к языковым моделям, написанным в ржавчине кем -то, кто очень мало знает о математике или нейронных сетях. Первоначальная версия была очень, очень сильно основана на удивительной информации и примере Python здесь: https://johanwind.github.io/2023/03/23/rwkv_details.html
Также см. Репозиторий создателя RWKV: https://github.com/blinkdl/chatrwkv/
Если загрузка в режиме 32 бит использует много памяти. Модель 3B использует около 11 ГБ оперативной памяти, а 7b, которую можно поместить на машине с 32 ГБ, которую вы готовы закрыть другие приложения или справиться с некоторым обменом. Даже загрузка в режиме 8 -бит использует достаточное количество памяти, но она упадет после завершения загрузки.
Вам понадобится ржавчина и груз, установленные: https://www.rust-lang.org/learn/get-started
Вам нужно будет скачать модель RWKV. Вот ссылка на то, чтобы заставить вас начать (около 820 МБ): https://huggingface.co/blinkdl/rwkv-4-pile-430m/resolve/main/rwkv-4-pile-430m-20220808-8066.pth
Также токенизатор здесь: https://github.com/blinkdl/chatrwkv/blob/main/20b_tokenizer.json
Файлы моделей Pytorch могут быть загружены напрямую. Если файлы заканчиваются .pt или .pth он будет загружен как модель Pytorch. Если это заканчивается .st или .safetensors то он будет загружен в качестве защитников. ПРИМЕЧАНИЕ . Поддержка Pytorch в настоящее время экспериментальна и может неправильно функционировать. Скорее всего, вы просто получите ошибку, если возникнет проблема, поэтому не должно быть опасно попробовать этот подход. Если вы хотите, вы можете отключить функцию torch и создать поддержку только для файлов форматирования Safetensors.
После этого вы должны быть в состоянии cargo run --release . Вы можете попробовать компиляцию без --release но, вероятно, все будет безумно медленным. Также попробуйте cargo run --release -- --help чтобы увидеть параметры командной линии.
Примечание . По умолчанию используется все логические ядра, см. Параметры командной линии.
При желании вы можете преобразовать файл модели .pth в формат Safetensors. Посмотрите на utils/pth_to_safetensors.py для примера. Для этого вам понадобятся настройка пакеты safetensors и torch Python. Я предлагаю сделать это в виртуальной среде. В настоящее время на этом этапе не так много преимуществ, так как файлы горелки могут быть загружены непосредственно в текущей версии.
Поддержка GGML в настоящее время нуждается в исправленной версии ggml и ggml-sys из проекта llama-rs .
Cargo.toml настроен на то, чтобы указывать на правильную ветвь в моей вилке, но это исчезнет, как только необходимые изменения будут объединены в GGML. Естественно, этот репо будет обновлен, но имейте в виду, что ваши компиляции могут начать сбой в конечном итоге, если вы пытаетесь использовать более старую версию, так как в конечном итоге эта ветка будет удалена.
Примечание: эта часть сейчас устарела. Я все еще рекомендую прочитать ссылки ниже. Также обратите внимание, что это описание основано на более простой версии модели RWKV только с четырьмя состояниями на уровень. В полной версии пять.
Вот (возможно, неправильное) описание высокого уровня шагов, связанных с оценкой модели. Вам нужно будет обратиться к источнику в smolrwkv/src/simple/model.rs чтобы это имело смысл.
Кроме того, настоятельно решительно подумайте о том, чтобы прочитать их первым:
Кстати, забавный факт: «Тенсор» звучит очень мочно, но это в основном просто массив. Одномерный тензор - это всего лишь одномерный массив, двухмерный тензор размеров - это двухмерный массив. Они могут обладать особыми свойствами (например, неизменными), но это не имеет значения для понимания концепции в целом. Если вы знаете массивы, у вас уже есть общее представление о тензорах.
Чтобы оценить токен:
x от ln0 .x к каждому слою последовательно, используя x слой, сгенерированный для следующего.x , в котором вписывались.ln1 на x и подайте его на смешение времени. Это использует тензор из части модели FFN.tm_state из состояния слоя и назовите его last_x . (Почему? Кто знает!)tm_num и tm_den как last_num , last_den .tm_[state,num,den] поэтому обновите состояние вашего уровня с помощью них.x , которые были получены из расчетов.x из смешивания времени в x ( x += time_mixing_x ).ln2 на x и подайте его в смешивание канала. Это использует тензоры из сетевой сети Feed Forward.cm_state из состояния слоя и назовите его last_x .cm_state , поэтому обновите состояние уровня.x , который был получен в результате расчета смешивания канала.x из микширования канала до x .x , который был результатом после оценки последнего слоя.Модель имеет список токенов, которые он «знает». Иногда знак равен слову, иногда это просто часть слова. Обычно существует большое количество жетонов, в диапазоне 30 000-60 000. Я считаю, что нынешние модели RWKV имеют 50 277 жетонов. В любом случае, вы получите список из 50 277 номеров с плавающей запятой после запуска модели.
Наибольшее значение из этого списка - токен, который прогнозирует модель, является наиболее вероятным продолжением и так далее. Если вы сгенерировали отсортированный список из 10-40 вероятностей токена и выберете его случайным образом, вы получите довольно разумный выход, относительно говоря. Справедливо, чтобы сказать, что крошечная модель 430 м не дает наиболее разумного результата в целом.
Хорошее объяснение того, как справиться с следующим шагом, когда у вас появится список вероятностей: https://huggingface.co/blog/how-to-generate
Существует различные сложные математические материалы, связанные с оценкой модели, но единственное, что действительно имеет значение, - это умножение матрицы ( pardot в источнике). В случае RWKV это умножение матрицы-вектора (2D-массив, умноженный на 1D массив). > 90% времени, потраченного на оценку модели, находится в этих вызовах умножения матрицы.
В режиме без GUGML обработка математики/массива здесь использует ящик ndarray . Он обеспечивает функцию .dot , однако это никогда не будет рассчитывать матричное-векторное умножение параллельно, даже если поддержка резьбы в ярке. Поскольку этот расчет так важен для производительности, я в итоге написал свою собственную функцию, чтобы разделить расчет на куски и запустить его параллельно. См. Функции в модуле dumdot в smolrwkv/src/util.rs .
Тот факт, что вы получите список вероятностей обратно и не является определенным «ответом» от модели, кажется приличным контраргументом с идеей, что LLMS или могут быть в некотором смысле. Когда вы смотрите на вывод из LLM, большую часть времени вы даже не увидите наиболее вероятный токен. Кроме того, интересный факт: когда вы подаете подсказку для модели, он составляет список вероятностей, как когда вы просите его о ответе. Тем не менее, эти вероятности просто выбрасываются, за исключением результата после обработки самого последнего токена.
Приглашение в жирном шрифчике. Итак, Деревные Змеи или Собаки Драконов? Мир может никогда не знать!
* Loading tokenizer from: ./20B_tokenizer.json
* Loading model from: ./RWKV-4-Pile-430M-20220808-8066.safetensors
* Discovering model structure.
- Loading layer 1/24
[...]
- Loading layer 24/24
* Loading non-layer tensors.
* Loaded: layers=24, embed=1024, vocab=50277
В шокирующем открытии ученый обнаружил стадо драконов, живущих в отдаленной, ранее неисследованной долине, в Тибете. Еще более удивительным для исследователей был тот факт, что драконы говорили идеально китайцам.
Все эти драконы говорили разные диалекты, и эти диалекты не совпадали с родным языком собак.
В попытке расшифровать то, что говорили эти драконы, они назвали драконов и обнаружили, что их язык отличается от человека.
«Драконы понимали человеческие слова и точнее человеческие языки. Драконы говорили на человеческом языке. Они также понимали правила для китайцев», - сказала исследовательская группа Mongabay.
Проведя исследование, они надеются пролить свет на таинственную историю драконов в отдаленных, отдаленных регионах мира, особенно в Тибете.
Исследовательский проект, опубликованный в журнале Open Science, также показывает, что драконы на самом деле являются рептилиями или aka Tree Snakes.
Дракон, не змея
По данным исследовательской группы, драконы, найденные в Тибете, являются гонкой собак, а не рептилия.
В то время как исследовательская группа все еще не смогла придумать какое -либо объяснение того, почему эти драконы живут в Тибете, ранее считалось, что они, скорее всего, присутствуют на суше возле Тибетского плато.
«Драконы живут там как часть великого плато Цинхай-Тибет, которое почти совершенно нетронуто, и все плато Цинхай-Тибет постепенно конвертировалось в сельскохозяйственное состояние. Следовательно, у них есть отличительная схема жевания на деревьях, и, вероятно, животные не слишком велики, чтобы их можно было держать в природе»,-объяснили исследователи.