Владислав Виноградов @jet-47
Разработчик ПО для ИИ
Information
- Rating
- Does not participate
- Location
- Нижний Новгород, Нижегородская обл., Россия
- Works in
- Date of birth
- Registered
- Activity
Specialization
Software Developer, Backend Developer
Lead
Git
C++
Software development
OOP
Linux
Python
Bash
CI/CD
Спасибо за вопросы)
На данный момент проект не доступен в opensource, но мы планируем это сделать (как для компилятора, так и для библиотеки оптимизированных операций).
Нет, используются стандартные платформо-независимые диалекты MLIR, такие как vector, arith, math, llvm.
Большая часть компилятора использует платформо-независимые оптимизации. Уже в начале разработки компилятор также работал и на x86 платформе, хотя это больше использовалось для разработки и отладки. На данный момент мы также начинаем более углубленное тестирование на ARM архитектуре.
Да, был разработан свой транслятор OpenVINO -> MLIR и свой OV диалект для представления OpenVINO модели в терминах MLIR. Сам OpenVINO на данные момент не использует MLIR ни в каком виде, но есть отдельный плагин (https://github.com/openvinotoolkit/npu_plugin) для NPU устройств, который также использует MLIR для реализации собственного тензорного компилятора.
В MLIR диалектом называется коллекция операций (а также типов и атрибутов), объединённых общим доменом. Например, диалект для OpenVINO модели, диалект для взаимодействия с GPU и т.п. Уровни абстракция - это скорее логическое разделение этапов работы компилятора. При этом тут нет однозначной 1-к-1 связи между диалектами и уровнями абстракций. Диалекты могут комбинироваться в рамках одного уровня, некоторые диалекты могут существовать на протяжении нескольких этапов компиляции. В данной статье указаны ключевые диалекты для каждого уровня, на самом деле на каждом уровне используются несколько диалектов. Так, например, диалекты linalg, affine, scf описывают итерации по тензорам на разном уровне абстракций, а для описания самих операций используются диалекты arith/math/vector. При lowering'е мы трансформируем linalg в affine, а затем affine в scf. При этом тело "цикла" не меняется. Векторизация происходит на этапе linalg диалекта.
Спасибо за интересные вопросы! Постараюсь ответить по порядку.
Вернее будет сказать, что для операций в этой библиотеке есть несколько вариантов реализации (скалярная, RVV 0.7, RVV 1.0). Скалярные реализации использовались в основном в качестве референса для тестирования и отладки, в их оптимизацию особо не вкладывались. Векторный код для разных версий был реализован либо отдельными функциями (с выбором на этапе компиляции через #ifdef), либо через использование С-интринзик компилятора (для большинства операций они совпадали, что позволяло держать одну версию кода для обеих версий векторного расширения).
Т.к. скалярные версии операций в библиотеки не были специально оптимизированы, сравнение с ними было не особо интересно. Вместо этого нашей командой было произведено сравнение с библиотекой XNNPACK. Это достаточно известная библиотека оптимизированных операций, применяемая в основном для ARM устройств. Она также работает и на RISC-V, но в данный момент в ней нет отдельных векторных реализация для этой архитектуры, только оптимизированный скалярный код.
Сравнение делалось на другом наборе моделей и на другой плате (LicheePI - https://sipeed.com/licheepi4a), замерялось число инференсов-в-cекунду (FPS, больше-лучше). Наши RVV оптимизации показали 2х и больше преимущество по сравнению с инференсом через связку TfLite+XNNPACK.
В рамках другой активности (тестирование Halide под RISC-V - https://github.com/dkurt/halide_riscv) были осуществлены некоторые наработки для поддержки RVV 0.7.1 в LLVM (https://github.com/dkurt/llvm-rvv-071). С полноценной реализацией поддержки RVV 0.7.1 в LLVM есть ряд нюансов:
Мейнтейнеры LLVM не особо настроены видеть эту поддержку в официальной версии LLVM. В интернете можно найти обсуждения по этой теме. Основной посыл от разработчиков LLVM - он поддерживает только официально ратифицированные версии расширений, что не относится к RVV 0.7.
Одновременная поддержка нескольких версий может быть не тривиальна. Лично мне тут трудно судить, ибо я плохо знаком с устройством бекендов в LLVM.
Есть вероятность, что в ближайшее время на рынке появятся устройства с поддержкой RVV 1.0 и эта задача потеряет актуальность.
log пока не реализован из-за отсутствия необходимости, exp реализована через аппроксимацию полиномом.