Всем привет! Меня зовут Николай Первухин. Я увлеченный разработчик на GoLang, работаю в Ozon Банке в группе разработки сервисов ЗСК (KYC).
Большинство статей о внешней видеокарте посвящены погоне за FPS в играх. Здесь же я хочу сконцентрироваться на том, как заставить её приносить пользу разработчику.
Как и многие удаленщики, я работаю на ноутбуке, который предоставила компания. Можно было выбрать Win/Mac/Linux — и, конечно, я выбрал Linux. Мне достался Lenovo T14 gen2, c процессором Intel i7 и интегрированным графическим чипом Iris Xe Graphics.
«Кроме установленного на ноутбук Ubuntu, терминала и Vim, истинному гуру-бекендеру больше ничего не нужно», — скажут некоторые.
Я пока не овладел таким уровнем аскетизма: хочется работать с комфортом в IDE, чтобы крутить круды и proto-файлы создавать прекрасный код. И поскольку я человек, а значит вершина программно-цифровой цепочки, я должен генерировать идеи, а основную работу за меня должна делать машина (в мечтах).
Первые попытки придать человечность ноутбуку
Ловлю себя на мысли, что тот, с кем я провожу все тернии дебага, кто разделяет со мной боль код-ревью (aka ноутбук) — не робот-андроид, а скорее продвинутая пишущая машинка. Учитывая мировой тренд увлечения генеративным ИИ, мы вместе с ноутбуком попытаемся «поумнеть».
Субъективно, я не сторонник облачных ИИ: отправлять куда-то свой код, надеясь на конфиденциальность… Звучит не очень безопасно — ну и помним, что СБ всегда на страже. Поэтому для одушевления цифрового товарища подходят только локальные решения.
Давным-давно в институте 30 лет назад я изучал ИИ, но мои знания уже давно протухли и ограничиваются теоретическими основами перцептрона. Короче, никуда не годятся. Поэтому мне хотелось найти максимально быстрое и простое решение. Перебрав несколько вариантов, я остановился на проекте Ollama, который можно использовать через Docker.
Как же я был удивлен, когда действительно всё установилось и заработало без проблем (ну почти).
Вот так одной командой можно запустить Ollama-сервис:
docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama
Я постучался на порт 11434 (нужен для работы с моделями через api) и сервис возвестил о нормальной работе: «Ollama is running».
Надо пояснить, что без установленной модели Ollama чист, как разум дитя. В моём случае нужна была не просто базовая языковая модель, которая помогла бы с рецептом свиных крылышек, а специальная, программистская — которую натаскивали на скриптах, кодах и прочей информации, понятной только нам с вами.
Немного о моделях
Оговорюсь, я не сильно погружался, прошёлся по верхам. И вот, какие модели мне удалось найти: Code LLama, StarCoder, DeepSeek Coder и, конечно, Codestral. Есть много подобных моделей, и нужно много времени, чтобы оценить плюсы и минусы каждой из них. Поэтому опишу опыт работы с теми, которые я лично попробовал.
Codestral от компании Mistral AI
Данную модель обучали на 80 языках программирования, и по заявлению создателей она значительно лучше по показателям релевантности по сравнению с базовыми моделями, существовавшими до неё.
Модель похожа на красивый Rolls-Royce: неторопливая, но очень качественная. Огорчила низкая скорость работы модели, но её можно немного ускорить — об этом расскажу позже.
Starcoder2
Это сразу 3 модели, обученных на разном количестве данных (3B, 7B и 15B). Их обучали на 600+ языках программирования. А также на естественных языках на основе Wikipedia, Arxiv и GitHub. Даже самая большая модель 15B работает в разы быстрее Codestral, но с большой вероятностью выдаёт полную дичь абсолютно не релевантный результат.
DeepSeek-Coder
Наверное, это тот самый компромисс между скоростью и адекватностью. DeepSeek — это тоже плеяда из нескольких моделей. Здесь их 4 с разным размером: 1.3B, 5.7B, 6.7B и 33B. Эту модель натаскивали на объемах данных как естественного языка (18% данных, в основном, английского языка), так и кода (82% данных). Результат быстрый и достаточно релевантный.
Пока я использую Codestral, мощную и одновременно простую для моих задач, и DeepSeek-Coder 6.7b, немного меньше, но быстрее.
Чтобы загрузить и установить модель требуется выполнить:
docker exec -it ollama ollama run codestral:22b
docker exec -it ollama ollama run deepseek-coder:6.7b
Скачается около 16Gb — позаботьтесь заранее, чтобы было свободное место. И сразу я бы рекомендовал установить модуль nomic-embed-text, он потребуется для плагина в GoLand:
docker exec -it ollama ollama run nomic-embed-text
Посмотреть, какие модели установлены, можно командой:
docker exec -it ollama ollama list
Результат выглядит примерно так:
NAME ID SIZE MODIFIED
deepseek-coder:6.7b ce298d984115 3.8 GB 10 minutes ago
starcoder2:15b 20cdb0f709c2 9.1 GB 42 hours ago
starcoder2:latest f67ae0f64584 1.7 GB 2 days ago
nomic-embed-text:latest 0a109f422b47 274 MB 5 days ago
codestral:22b fcc0019dcee9 12 GB 5 days ago
Теперь всё готово, чтобы начать использовать модель непосредственно из GoLand. Для связи с сервисом необходимо установить plugin continue (continue.dev). Есть также вариант для VSCode, если по каким-то причинам нам стало тяжелее пользоваться GoLand. На момент написания статьи плагин работает стабильно для GoLand 2024.3 EAP, в более ранних версиях были проблемы, которые решались изменением runtime для GoLand на более старый.
После установки сразу открываем настройки плагина (шестеренка внизу окна плагина) и исправляем конфиг на локальный.
Приведу пример моего конфига для работы с локальным сервисом Ollama и моделями Codestral и DeepDeek Coder:
{
"models": [
{
"title": "Codestral",
"apiBase": "http://localhost:11434/",
"provider": "ollama",
"model": "codestral:22b",
"contextLength": 2048
},
{
"title": "Deepseek-Coder",
"apiBase": "http://localhost:11434/",
"provider": "ollama",
"model": "deepseek-coder:6.7b"
}
],
"tabAutocompleteModel": {
"title": "Deepseek-Coder",
"provider": "ollama",
"model": "deepseek-coder:6.7b",
"apiBase": "http://localhost:11434/"
},
"contextProviders": [
{
"name": "diff",
"params": {}
},
{
"name": "folder",
"params": {}
},
{
"name": "codebase",
"params": {}
}
],
"embeddingsProvider": {
"title": "embeding",
"provider": "ollama",
"model": "nomic-embed-text:latest",
"apiBase": "http://localhost:11434/"
}
}
После перезапуска GoLand моделью можно пользоваться — но только если есть много свободного времени:
Инициализация модели (первый запрос) на моем компьютере заняла 10–15 минут. Часто модель загружается в оперативную память и чувствует там себя хорошо, но использует её почти всю…
Скорость выдачи результата примерно 1 слово в 5 секунд. Обычно для ускорения процесса разработки требуется строгий начальник, в данном же случае сойдет и ускоритель. В нашем случае графический внешний ускоритель.
Тестируем ИИ вместе с видеокартой
Про техническую часть подключения видеокарты выйдет отдельная часть статьи. Считаем, что физически видеокарту я уже подключил, установил драйверы, Cuda и дополнение к Docker для проброса видеокарты внутрь контейнера. Поэтому продолжаем работать с Ollama.
Запускаем проект Ollama с использованием Docker и видеокарты (добавляется параметр проброса всех видеокарт внутрь контейнера):
docker run -d --gpus=all -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama
В логах контейнера будет запись об использовании видеокарты:
.. library=cuda compute=8.6 driver=12.4 name="NVIDIA GeForce RTX 3060" total="11.8 GiB" available="10.6 GiB"
И вот реальное чудо наступило! Наша модель работает достаточно быстро. Непосредственно из GoLand делаем запросы:
Инициализация (первый запрос) идёт около 20 секунд
Обработка запроса — гораздо быстрее (в зависимости от модели соизмеримо со скоростью облачных ИИ)
Загрузку видеокарты в момент запроса можно отследить командой nvtop:
Как видно из графика, идёт большая утилизация видеопамяти и средняя утилизация gpu.
Для ещё большего ускорения можно настраивать размер контекста: чем меньше, тем модель работает быстрее. Но учитывайте, что тогда уменьшается сложность алгоритма, а ответ будет менее релевантным. Это особенно актуально для больших моделей типа Codestral. Для своей видеокарты пока я выбрал почти минимальный размер — 2048.
"models": [
{
"title": "Codestral",
"apiBase": "http://localhost:11434/",
"provider": "ollama",
"model": "codestral:22b",
"contextLength": 2048
}
] ...
Пример работы
Я был приятно удивлен, что неподготовленный человек типа меня может сразу начать работать с моделью достаточно нативно.
Например, можно выделить фрагмент в коде, добавить его в контекст и спросить прямо на русском языке: «Что делает этот код?»
Еще можно выделить функцию и написать для нее тест. Вот это мне особенно понравилось — при всей моей любви к тестам:
Из более сложного, можно попробовать сгенерировать что-то новое, например, вот такое: «Создай модуль сохранения в таблицу Calls данных с идентификатором и именем на языке Go с использованием фреймворка go-jet по-русски». Все эти уточнения важны: если не уточнить язык, автоматически выберется Python, если не упомянуть jet, будет GORM и тп. Но даже с такой задачей модель справляется неплохо:
Из полезного, попробовал добавить в контекст большой кусок кода и попросил сделать code-review. Понравилось, что язык ответов довольно живой (да что она себе позволяет, эта бездушная машина?!)
Вот так выглядит ответ от модели Starcoder — достаточно «четкий», как будто общаешься с человеком не в своем районе:
Несколько видео-примеров по работе с моделями Codestral и DeepSeek Coder. Я использовал один и тот же запрос на разных моделях:
Codestral даёт очень аккуратный, но достаточно медленный ответ:
DeepSeek Coder быстрый и достаточно релевантный:
Выводы по ИИ части:
Что ж, хотя Ollama пока не берет сама задачу в Jira и не коммитит её за меня (даже не знаю, хорошо это или плохо), но польза модели уже очевидна.
Модель может использовать даже новичок. Например, для таких случаев:
генерить простые тесты,
искать примеры использования фреймворков,
рефакторить код, резюмировать, что написано в том или ином коммите и тп.
Контекст имеет смысл. Модель оперирует запросом и тем, что вы даете ей на вход — будь то кусок кода, файл или несколько файлов. Плагин continue автоматически производит индексацию проекта при открытии, поэтому можно использовать в запросах ключевые слова @codebase, @folder, @file для уточнения контекста. Можно спросить, как связаны файлы — c Go это особенно актуально при наличии 100500 интерфейсов к одной реализации. Но чем точнее вы формируете запрос, тем релевантнее становится выдача. Стоит учитывать, что размер контекста лимитирован и влияет на производительность.
Нужно учиться формировать запросы и экспериментировать с моделями. Как в Google мы интуитивно учились правильно формулировать поисковый запрос, так и здесь. Навык написания правильных запросов оттачивается только практикой: важно чётко формулировать, что нужно сделать (порой этого так не хватает в задачах от аналитиков, правда?)
Можно нагенерить большой проект используя различные технологии и языки. Напомню, модель знает 80 языков программирования, а вы?