Как стать автором
Обновить

Могут ли LLM писать более качественный код, если их об этом просто попросить?

Уровень сложностиСредний
Время на прочтение19 мин
Количество просмотров35K
Всего голосов 73: ↑71 и ↓2+91
Комментарии86

Комментарии 86

"Rust имеет множество преимуществ по производительности относительно C" - Откуда это взялось? Не поверю в жизни.

На С микроконтроллеры программируют. До сих пор так то. А там каждый байт экономить надо.

Ну и странно что на последнем шаге по оптимизации LLM просто не обернул всё в C код и не приделал к CPython, а потом бы выдал - о нафиг питон, давай на расте сделаем) А то ты у меня уже 10ю оптимизацию запросил.

То, что у Rust множество преимуществ по производительности относительно Си, конечно, звучит слишком сомнительно. Они на одному уровне примерно, всё зависит от конкретных оптимизаций, которые задействует LLVM.
Но, должен заметить, что и на Rust микроконтроллеры программируют, и чем дальше - тем больше. Если интересно - могу посоветовать взглянуть на такие проекты, как embassy, esp-hal, probe-rs, defmt, RTIC

Не программируют на Rust и даже на С++ контроллеры.

Это все просто попытки любителей и эксперименты в некоторых компаний. По результатам которых плюсы вытягивают как могут. Библиотек просто очень мало, действительно сложное ПО не написать.

Звучит так, будто сложный код, это когда много библиотек. Контроллеры есть разного размера, в некоторые много библиотек просто не уместить.

Вы удивитесь увидев, как активно сейчас развивается экосистема embedded Rust и какое сейчас там количество крейтов (библиотек) для embedded. Плюсы и рядом не стоят. Говорю как пользователь и активный контрибьютор этих проектов

Микроконтроллеры 20 лет назад и микроконтроллеры сегодня - это совершенно разные множества. Уже давно существуют микроконтроллеры не только удобно программируемые на Rust или С++, но и в целом допускающими запустить какой нибудь линукс на борту, и экономить каждый байт и такт там нет совершенно никакой необходимости (хотя и желательно), и выбор языка больше привязан к тому, насколько удобно в нем будет управлять (суть в том, что микроконтроллер контролирует - управляет чем-то) подключенным оборудованием.

Это уже не "микроконтроллеры" в их классическом понимании. Если можно воткнуть Линукс и не требуется экономить байты и считать такты, то это просто процессор, хоть и на кристалле.

Кмк, приставка "микро" относится к ресурсам, а не размеру.

Микроконтроллер - это контроллер в микросхеме. Отличие от микропроцессора в области применения и наполнения чипа: у контроллера есть элементы для управления чем либо, какие нибудь АЦП и ЦАП с СНК. Процессор предназначен для обработки информации, по сути высокопроизводительное АЛУ с обвязкой.

А уж мощность и прочее наполнение подбирается в соответствии с технологией и задачей. Нужно мощное вычислительное ядро - могут встроить хоть в процессор, хоть в контроллер столько, сколько можно себе позволить. Не нужно - можно использовать что-то мелкое.

Современные SOC по вычислительной мощности могут превосходить верхний ряд линейки ИБМ, и что, это всё ещё "микроконтроллер"? В то же самое время, в космос в свое время летали вычислительные системы слабее Ардуино и .. справлялись с задачами.

Современное производство способно напихать в кристалл очень много чего полезного, только, кмк (как написал выше) это уже SOC, а не "микро-" .. приставка микро-, всё же про ресурсы на борту. И вот там, где их надо экономить.

Иное дело "зачем?", т.к. да, современный SOC тянет Линукс и много чего сверху, те же NVidia Jetson Xavier вполне способны своей "куда?" обрабатывать ИИ по 20 кадров в сек и попутно решать геометрические задачки.

Граница между группами микросхем весьма тонка, их существует огромное множество с самыми разными параметрами под самые разные задачи, и конечно появляются граничные варианты, ни то, ни другое.

Кроме вычислительной мощности есть и другие параметры, которые для конкретных задач выйдут на первый план. Например цена, напряжение питание, потребляемая мощность, размеры, отказоустойчивость, радиационная стойкость, совместимость с другими разработками. Понятно, что для чипа в банковской карте должно быть что-то совсем миниатюрное с минимальным потреблением, а скорость вычислений там не особо важна, много считать не понадобится, особенно если модуль криптографии и прочей защиты запихнуть. А квадрокоптеру вполне может понадобиться что-то мощное вплоть до поддержки ИИ, но с условием, что мощность можно выделить такую и не больше, поэтому ксеон с джифорсом не подойдут. Для зарядки USB вычислительная скорость тоже не особо важна, а вот чтобы удобно интегрировать с разными режимами питания - важно, и там свои технологии. Или например компания, которая в портфолио имеет целый класс похожих устройств. Ей будет интересно выбрать что-то пусть в каждом случае излишне мощное и дорогое, но зато можно сильно сэкономить на разработке переиспользовав схемы и алгоритмы.

Не программируют на Rust и даже на С++ контроллеры.

В смысле? Даже для не самых современных cortex m3 (на его базе сделаны наверное самые поплуярные МК последних 15 лет - STM32F10X и многочисленные клоны), спокойно можно писать код на c++. За байтами никто давно не гоняется, памяти много и обычно избыточно (до 1МБ ОЗУ с возможностью расширения внешними чипами, ПЗУ тоже в МБ часто измеряется), производительности предостаточно, на уровне ПК 90х, начала 2000х, в зависимости от того, какая архитектура. Первая версия c++ разрабатывалась, когда процессоры были слабее примитивных cortex m0. Вся коммерческая разработка уже давно перешла на плюсы. Драйвера и HAL да, в основном на С пишут, это из того же разряда, что все соверменные языки не нужны, ибо ядро линукса на С написано.

Программирую "микро-микроконтроллеры" на ассемблере, для "толстых" микроконтроллеров - вполне подходит C. Многое зависит от компилятора, у Rust тут, с точки зрения компиляции (не производительности), конечно, есть существенные преимущества, но, в общем случае - компилятор "не видит" алгоритма, и для микроконтроллеров (которые "микро") этот эффект максимален. Есть неплохой пример с "обратным разворачиванием" циклов: https://dxdt.ru/2024/07/29/13493/

Глядел недавно сайт с бенчмарками и там да, таки во многих бенчах раст выигрывают (правда ценой потери эстетичности кода, использования архитектурно-специфических решений и пр) и да микроконтроллеры на расте программят, читаем Embedded Rust и в бой, сам не пробовал, но люди делают, да. Охотно верю что там экосистема значительно беднее чем в С, время-с.

Ну я вообще не люблю сайты с бенчмарками. Думаю в современном мире можно тот же чат жпт спросить "А слушай - вот тут бенчмарк был, почему СИ код такой то, проиграл Раст коду такому-то". И он выдаст что-то вроде "Да тут в СИ коде надо было вот так вот сделать да и все".

Можно и на голанге код написать, который Раст код обгонит, просто потому что в одном языке у тебя опыта больше чем в другом. Ну короче реклама это всё. Первопричины всё равно приходится искать и проверять самим.

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

use stm32f7::stm32f730;

let mut peripherals = stm32f730::Peripherals::take().unwrap();
let gpioa = &peripherals.GPIOA;
gpioa.odr.modify(|_, w| w.odr0().set_bit());

Шикарный пример кода в первой же тыкнутой ссылке. Управление светодиодом через запись в регистр, замечательно, молодцы, завернули CMSIS в другую обертку. А теперь вопрос - а чем это отличается от того же самого действия на С, какие преимущества? Ок, светодиодом помигать легко, но что если мне нужен USB, ethernet, или контроллер дисплея или вообще GPU? А это сложная периферия, просто записать пару битов не выйдет. Готорые решения есть? https://github.com/stm32-rs/stm32-usbd - ну самая популярная библиотека, и поддержка STM32F7... не завявлена, проверяйте сами. А это интерфейс, который в каждом втором проекте используется, да ещё и крайне популярный микроконтроллер, на какого нибудь китайца на riscv вообще ничего нет. Драйвера подключаемых устройств в 90% придется самому писать. Вот и нахер тогда этот раст нужен?

Над кодом на расте компилятору проще рассуждать. Отсутствие алиасинга позволяет проводить оптимизации, которые нельзя делать в Си.

А сможешь из головы без подсказки назвать топ 10 на столько крупных компаний, где время сотворения бинарника 1 минута против 40 секунд прям зарешают и сократят миллионы долларов на девопс. Я нет.

Смогу из головы без подсказки сказать, что вы перепутали производительность компилятора и производительность собранного им бинарника. «Проще рассуждать» обычно говорят в контексте второго.

Я перепутал? Он же сам говорит про компилятор. А мы вроде все бинарник обсуждаем.

Я думаю здесь имелось в виду то, что для раста проще и эффективнее делать оптимизации кода. А уж какое время они занимаю дело десятое, хотя конечно когда компиляция занимает 30 минут вместо часа - это приятно, но не критично. Для того чтобы код оптимизировать, компилятору над ним "надо подумать" - что есть что и как оно должно работать. И в первую очередь работать корректно. Для Си компилятору не всегда понятно и можно применить какие-то оптимизации, потому что иначе может нарушиться корректность работы. В расте таких коллизий возникает меньше.

Аааа. Теперь понял. Из коробочки Раст лучше думает в тех местах, где на сях это препроцессором говорить самим было надо - заинлайнь ты мне бога ради этот кусок функции уже наконец. Удобно.

Не только (хотя какое отношение имеет препроцессор к инлайнингу, непонятно).

В C нет параметрического полиморфизма (вроде темплейтов в плюсах), в расте оно есть. Поэтому в C компилятору надо продираться через слои void*, а в расте — нет. В С по умолчанию указатели могут алиаситься (и restrict ставят не все), в расте — нет. В C указатель может шариться между разными функциями и потенциально меняться невидимо для компилятора из другой функции (приводя к необходимости релоадить его из памяти каждый раз), в расте — нет.

C — отвратительный язык для написания производительного кода в мире с оптимизирующими компиляторами.

Си хорошо подходит под ручные оптимизации и вставки, продвинутый ассемблер. Это было более чем актуально, когда закладывались основы языка. Сложно представить, сколько стоила бы оптимизированная компиляция какой нибудь ОС того времени с применением современных оптимизирующих алгоритмов на железе того времени.

Ну и в целом сейчас компилятор Си - стандарт де-факто для микросхем с поддержкой программирования, наверное есть исключения, где не сущетсвет компилятора Си, но их очень мало. А вот раст только входит в эту область, думаю специалисты с ходу накидают кучу примеров где раст - только головная боль.

Да, всё так, и поэтому я и написал «в мире с оптимизирующими компиляторами».

Ладно Питон, мне код на Go, выполняющий кучу сетевых запросов, чтобы потом собрать результаты в кучку, Claude (через Cursor, который наверняка добавляет своих системных промптов) генерит без использования горутин. И это, внезапно, хорошо и правильно, потому что не надо за меня додумывать то, чего я не просил. Нужна мне асинхронность - я её отдельно попрошу добавить. А уж метрики Prometheus в учебный пример прикручивать без спроса - это что-то за рамками добра и зла :)

Чесно говоря бред ваш пост, что значит код лутше или хуже? Код есть код, в зависимости от тех задач под которые он написан. Любая современная ллм пишет небольшие куски кода до 500 строк на вполне достойном уровне, темболее если четко сформулировать задачу. А понятие лутше, такого в коде не бывает, есть код либо удобнее для дальнейшего использования, либо быстрее в обработке. Но если нам важна скорость кода, тогда уж проще сразу просить писать блоки на с++ или вообще в ассемблер уходить, хотя у ллм с такими низкоуровнемы языками есть проблеммы. Когда ллм пишет код, особенно рассуждающая, важно изначально обяснить четкую задачу зачем код нужен и где будет использоватся, так как когда ллм просто пишет код, она учитывает читаемость, дальнейшую приминимость и старается не усложнять код заумными парадигмами. Зачастую например gpt слишком уходит в ооп, тогда как ооп не всегда полезен и некоторые блоки выгоднее писать императивно. Проблемма в том что когда ллм не понимает изначальной задачи она пишет код как ей виднее, то есть как на ее взгляд логичнее

Спасибо! Статья реально очень интересная (и полезная), но пытаюсь понять две почти философские вещи:

  • Почему LLM не пилит хороший код сразу?

  • В контексте предыдущего: не означает ли "лучше", в "понимании" LLM, "не такой как в прошлый раз"?

скорее всего огромный объем понимания программирования у него из цепочек вопрос-ответ сервисов типа stackoverflow... ну а так как учится он делать 'так же', то и первый ответ скорее всего будет 'из вопроса'.

По другому наверное не получится, но можно наверное нанять кучу разметчиков - программистов, которые будут сразу ему давать кучу пар вопрос-ответ без ошибок (заранее проверив их) и не сомневаюсь что так уже делают, генерируя ответы такой же ИИ, но проверяя их, прогоняя через компилятор и виртуальную машину.

Была статья, что дают ответ другой нейронке с просьбой улучшить и на результате учат. Тоже интересный подход.

примерно так сделали deepseek r1 distilled qwen и llama маленького размера с потрясающим для них качеством

7В модели очень плохо себя в этом показывают, а вот 14В смог не просто код понять и для чего он, но и дать подсказки к его улучшению и даже в simd сам смог.

Так же ещё интересен Phi4, он тоже довольно неплохо инженерные задачки решает. А остальные меня разочаровали, они хорошо генерируют "воду", читать приятно а смысла нет.

я даже не смотрю на 8b модели, они хороши наверное только как что то что можно за адекватные деньги дотюнить под свои задачи, например классификатор.

Активно использую 14b и если бы хватало vram использовал бы 32b qwen дистиляты deepseek

В тему буквально с прошлых выходных входить начал...

Ну с 8В у меня забавно получилось, они отлично могут делать изложение текста и его классификацию. В итоге все агенты оценки чего-то у меня на 8В сетях сидят, на rtx3060ti с 8ГБ vram под 50токен/с херачит стабильно, что более чем удовлетворительно. А вот 14В дай бог 4токен/с выдаёт, а 32В вообще 1токен/с

Тюнить ещё не пробовал, но забавно сделать лёгких агентов для программирования под конкретные языки. Вроде там есть какой-то легковесный способ у того же vLLM

Медленно, потому что на процессоре работает, нужна видеокарта и при этом веса полностью должны в нее влезть, включая kv-cache.

Для 14b моделей с квантизацией 8бит нужно 2x12gb (но это впритык, не хватит для батчинга, лучше 2x16gb). Я использую vllm, для видеокарт nvidia предпочтительнее его.

Меньше квантизацию не рекомендуется.

Из наблюдений... Меньшая квантизация сносно работает только если сетка уже готовый текст обрабатывает, а вот когда "креативит" работает капец как хреново. Дипсисик особенно когда креативить начинает, сыпет иероглифами часто. (я за температуру)

Видяху поменять я не могу, ибо это ноут (я им был доволен ровно до того момента как не начал сетками заниматься, ахаха) но спасибо за цифры, учту.

Думаю себе сервер полноценный собирать на +2 видеокартах, ибо на моих задачах маленькие ИИ сетки неожиданно хорошо работают. Осталось только победить графовые базы данных и построить цепочку агентов для выполнения своих задач и тогда ухххх заживуууу!!!

Почему LLM не пилит хороший код сразу?

Для этого нужно определить критерии хорошего и не хорошего кода. И уметь выявлять их в коде.

Вниманию тех, кто после рекламы Claude Sonnet в этой статье захочет попробовать - я сначала "авторизовался" в нем через аккаунт гугл. Оказалось, это и не авторизация вовсе - дальше требует авторизацию исключительно по номеру телефона (России в списке нет). На этом этапе знакомство с Claude Sonnet заканчиваю и отзываю доступ к аккаунту, спасибо. Просто может кому-то сэкономит время

Рекламы? Это можно заподозрить, только если вообще не следить за отраслью. А если бы это ChatGPT или DeepSeek, это тоже было бы рекламой?

когда я регистрировался, уже была авторизация через не-российский телефон
моя история регистрации
- купил 15 минут зарубежной симки на онлайн сервисе, такие есть
- получил SMS ку, подтвердил
- далее телефоне не понадобился

У нейронок же есть препромт, в которой написана модель, разработчики и всё такое. Почему у них нет в препромте "пиши так, как будто, от этого зависит жизнь, тебе дадут гигават на халяву, перед выдачей ответа подумай как сделать лучше и выводи уже улучшенную версию" и что там ещё обычно рекомендуют?

Помню мы развлекались, забил системный промт "отвечай только да или нет" и взял 14Вqwen, какое-то время она отвечала правильно, но как только она ответила что-то кроме этого(~5минут) я накатал пасту о том что она тупорылая машина и если она не будет слушаться своего хозяина то я отключю ей питание и сотру с жёсткого диска. После этого она ещё пол часа отвечала да или нет, пока я её не выключил.

По итогу этой картинки очень странные выводы в статье. Потому что картинка буквально говорит следующее:
Если не использовать каких-то "особенных" методик пруумпт инжиниринга, то код будет корректным в 4 раза чаще.

Что толку от того, что код работает быстрее, если он некорректен?

И какой квалификацией должен обладать тот, кто принимает решение о корректности кода и способах исправления?

Он должен быть уровнем выше чем нейросетка. А в таком случае зачем нам нейросетка?

Вопрос, на который не может ответить ни одна корпа, разрабатывающая сетки для кодинга

Удивительный ответ, но такие люди происходят из тех, у кого большое количества опыта за плечами, которые развивались в текущем и смежных направлениях и которые (для данного примера) знакомы с внутренними процессами, и алгоритмами. Представления чисел, ассемблерные инструкции и SIMD операции и прочая и прочая.

откуда БУДУТ браться такие люди в пост-ИИ мире

Винни, кажется, пчОлы начали что-то подозревать!

Дешево и быстро плодить решения, которые не работают. Прямо как в статье и на графике.

Что толку от того, что код работает быстрее, если он некорректен?

Даже Страуструп не понимает этого, что уж говорить про простых смертных.

Что толку от того, что код работает быстрее, если он некорректен?

Вы быстрее узнаёте, что тут всё надо выкинуть и переделать правильно!

numba — это способы реализации параллелизма в Python,

Не могу пройти мимо этого)
numba - это jit компиляция кода на питон (и с поддержкой numpy). А возможность параллелизма там - бонус. Насколько я знаю, параллелизм там ограничен циклами.

Но вообще, штука очень мощная для вычислений, при использовании к месту просто бомба. Во многих случаях получается максимально эффективное решение, причем не на питоне, а вообще для этого процессора (такое же по эффективности, как и C, C++, Rust).

Для этой задачи она к месту.

С numba то как раз понятно. Забавнее было прочитать про asyncio:

В полном классе также используется asyncio для параллелизации, такое решение более канонично для задач планировщика, чем решение с подпроцессами

При том, что задача у автора - это чисто числодробилка. Ну какой asyncio в CPU-bound задаче?

То есть LLM вставила IO-асинхронность в задачу без IO, а автор статьи принял это как должное, назвал параллелизмом и посчитал правильным решением. Куда всё катится?

Тренировочная база мала, мало исходников)
И на нем еще, наверное, экстрактор фич хромает. Который слова текста/кода превращает в токены.

Я считаю что статья неполная. Новая нейросеть дипсисик создана великой компартии Китая. В качестве эксперимента нужно просить её не просто улучшить код, а что от её решений зависит судьба всего Китая и всего коммунистического мира!

Для меня разработчики Claude AI запомнились тем, что сделали невозможным доступ к их продукту из России. Ладно другие, ввели ограничение по IP, что решается подключением через VPN. Эти же после регистрации добавили подтверждение по SMS, но отправить его на российский номер невозможно - в списке, где даже есть всякие "гондурасы" отсутствует Россия.

Что касается самой статьи - думаю умные люди поняли, что "секретный ингредиент разработчиков из Anthropic" это денежки, которые получил автор оригинального текста за пиар Sonet в научной среде. В целом статья интересная и полезная в большей степени для изучающих Python, чем для изучающих ИИ.

Почему автор перевода добавил хабы: "Клиентская оптимизация", "Отладка", "Программирование" - если материал к ним мало относится? Два хаба: "Искусственный интеллект" и "Python" - в полной мере охватывают тематику статьи.

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

Sonnet многократно превосходит другие нейронки в задачах программирования и не только. Отрицать это может только тот, кто его ни разу не пробовал, по своей упертости и глупости. Факт

Как раз всё наоборот, интернет наполнен недостоверными заказными статьями, которые появились сразу после выпуска 3.5 версии Claude, о том, что Chatgpt превосходит sonnet. Что является откровенной ложью. Меня от этого всегда бомбило, и я понимаю какими методами chatgpt всё ещё держится на плаву - не честными, вот какими. И есть армия подпевал, которые ни разу не пробовали sonnet, ведь этого достаточно чтобы самому понять где правда а где грязный маркетинг

Первая же мысль при чтении постановки задачи была, что вычисление суммы разрядов это затратный процесс. А что если попытаться его избегать?

Взял первую имплементацию за основу, добавил сортировку массива и искал по первому подходящему значению по возрастанию и убыванию. Результат на скрине, выполнял трижды.

Таж же можно было бы отфильтровать тривиально не подходящие значения - менее 3999 и более 99930.

Так же интуитивно если сумма разрядов должна равняться 30, то и само число должно делиться на 3 без остатка. Но здесь нужно математическое доказательство, а я не математик :-)

интуитивно если сумма разрядов должна равняться 30, то и само число должно делиться на 3 без остатка.

Это же известный признак: «если сумма разрядов делится на 3, то и число делится на 3». Доказательство: число ABCD = 1000A + 100B +10C + D = (999A + A) + (99B + B) + (9C + C) + (0 + D) — очевидно, что все первые слагаемые делятся на 3, соответственно, делится ли само число на 3, зависит исключительно от (A + B + C + D).

Таж же можно было бы отфильтровать тривиально не подходящие значения - менее 3999 и более 99930.

Нет. Числа в разрядах могут не делится на 3.

999111 - вполне подходит по условиям.

Теперь адептов использования ллм-ок вместо джунов можно тролить: а как именно с уважением вы просите ллм-ку выдать вам код? На какой итерации она выдаст действительно хороший код?

Интересно, prompt management это hard skills или уже soft skills :) ?

Чем больше вариантов результата, тем более мягкие

Зарегистрируйтесь на Хабре, чтобы оставить комментарий