Внешняя видеокарта backend-разработчика, или как заставить лучшего друга перестать тупить и начать помогать (часть 1)

от автора

Всем привет! Меня зовут Николай Первухин. Я увлеченный разработчик на 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    ce298d9841153.8 GB10 minutes ago starcoder2:15b         20cdb0f709c29.1 GB42 hours ago   starcoder2:latest      f67ae0f645841.7 GB2 days ago     nomic-embed-text:latest0a109f422b47274 MB5 days ago     codestral:22b          fcc0019dcee912 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 моделью можно пользоваться — но только если есть много свободного времени:

  1. Инициализация модели (первый запрос) на моем компьютере заняла 10–15 минут. Часто модель загружается в оперативную память и чувствует там себя хорошо, но использует её почти всю…

  2. Скорость выдачи результата примерно 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 делаем запросы:

  1. Инициализация (первый запрос) идёт около 20 секунд

  2. Обработка запроса — гораздо быстрее (в зависимости от модели соизмеримо со скоростью облачных ИИ)

Загрузку видеокарты в момент запроса можно отследить командой 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 языков программирования, а вы?


ссылка на оригинал статьи https://habr.com/ru/articles/848030/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *