Всем привет! Меня зовут Николай Первухин. Я увлеченный разработчик на 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 моделью можно пользоваться — но только если есть много свободного времени:

  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 языков программирования, а вы?

Комментарии (5)


  1. Rampage
    04.10.2024 11:31
    +1

    Спасибо, очень интересно!


  1. iwram
    04.10.2024 11:31
    +4

    Спасибо. Очень интересно. А вы проверяли что нейросеть ничего в интернет не отправляет? Например при использовании koboldcpp и различных моделей внезапно запросы с хоста на котором работает модель идут такие запросы:

    apex-domain-nlb-610ce55e8d445742.elb.us-east-1.amazonaws.com.:A:60=34.194.97.138
    apex-domain-nlb-610ce55e8d445742.elb.us-east-1.amazonaws.com.:A:60=34.200.2.98>

    Вед не я один логирую все запросы с роутера и предварительно внешние обученые модели файрволить, чтобы безопасность была безопасной. Наверное получится хорошая статья если получится еще вытащить тело хоста и узнать что отправляется "провайдеру бесплатной модели".


    1. Nikolay_Pervukhin Автор
      04.10.2024 11:31

      Спасибо большое за крутой комментарий, тема безопасности это как раз основной мотиватор использования локальных моделей! Специально по хостам не мониторил, но какой-то необычной активности не наблюдал. Думаю для реальных проектов для контейнера с ollama необходимо создавать контейнер в другой сетке без интернета в докере.


  1. JuliaKur
    04.10.2024 11:31
    +1

    Крутая статья!


  1. ryba1967
    04.10.2024 11:31

    Ноутбук с Linux это, наверное, минимально ограничивающий программиста вариант с точки зрения политик и возможностей СБ ? Root, свобода в установке софта?