Читать в телеге. Когда-то там были посты не только от меня.
Аннотации массивов в java
Психолог: заковыристые типы в Java не существуют, они не могут причинить тебе вреда.
Тем временем java: @Nullable List<? extends @Nullable Object> @NotNull [] @Nullable [] someVar
.
Вьетнамские флешбеки от сишных указателей.
Если серьезно, то массивы всегда были “особенными”: вроде и не примитивы, но и не классы. Еще и куча исключений, настолько, что это в Kotlin просочилось.
CRDT
Отличная интерактивная статья про CDRT (Conflict-free Replicated Data Type).
Это по сути фундамент для идей Клеппмана про Local-first приложения.
Двойные и тройные слеши в пути
Нашел прекрасное. В POSIX ////some/path
, ///some/path
и /some/path
— это одно и то же, но при этом не то же самое что //some/path
. 3 и более слешей спереди превращаются в одинарный слеш, а вот обработка 2 слэшей может зависеть от системы/реализации. И нет, это не из-за Microsoft.
В большинстве случаев, например в Cygwin, //host/path
интерпретируется как сетевой ресурс. Но не сетью единой: например, в Bazel //
используются для адресации таргетов.
Локальный запуск LLM
TLDR: Если вам нужен простой локальный GPT, попробуйте Ollama. И разумеется, если у вас не зверь-машина, то все модели будут тупее ChatGPT.
Вообще я поразился, как много уже доступно предобученных моделей для скачивания — тысячи их! Все я пробовать, разумеется, не стал, выборочно посмотрел готовое с интерфейсами.
- Сначала я попробовал LM Studio. У него захламленный и запутанный интерфейс. Кроме того, это закрытое ПО, и нет поддержки для Linux. Однако там без проблем можно скачивать LLM-модели и легко переключаться между ними. Для перебора LLM — сойдет. Я попробовал модель “codellama instruct 7B q4” — пишет плохонький Python-код и предлагает плохие советы по Gradle.
- Затем я попробовал GPT4All. Довольно минималистичный интерфейс, хоть и лагает иногда, есть встроенная функция дообучения на локальных документах. Однако функция скачивания моделей сломана. Я использовал “GPT4All Falcon q4”. Он выдаёт абсолютный бред в ответ на вопросы по Gradle даже когда дообучен на документации, иронично указывая точные страницы из PDF-файла исходных данных.
- После этого я попробовал Ollama. Нет GUI, но с ней меньше всего гемора, ИМХО. Немного неудобен многострочный ввод (решается тройными кавычками). Иногда модель ломается и выдаёт несвязанные данные из-за проблем с парсингом. Увы, я не нашёл простого способа дообучить модель на локальных файлах. Я использовал модель “llama2-uncensored” с ним. Да, вы прочитали правильно, ее можно спросить, как роскомнадзорнуться, например (Я покекал с “Ultimately, the best way to RKN is one that you feel confident will ensure your safety and comfort during the process, with minimal risk of unforeseen consequences or complications”). Думаю, это приемлемая замена для GPT — все равно тупая, но зато без тормозов. Для вопросов по Gradle модель давала плохие ответы, но по крайней мере они содержали полезные части, а не только дичь.
- Наконец, я ознакомился с PrivateGPT. Установка не очень удобная, но и ничего сложного. Тоже нет GUI, но можно дообучать. Я использовал рекомендованную модель “gpt4all-j-v1.3-groovy”, дообученную на документации Gradle. Полный бред в ответ на вопросы по Gradle, еще и цитирует несуществующий текст из руководства.
- Есть еще LLamaGPT, который будет удобнее запустить в докере, но до него руки не дошли.
Теоретически можно загрузить модель Ollama в интерфейс GPT4All и дообучить, но я заленился это делать.
Уведомления от сервера клиенту
На прошлой работе, когда надо было выбрать технологию для отправки уведомлений клиентам, остановились на Centrifugo — довольно классный сервер для отправки сообщений по веб-сокетам (там были свои приколы, но зато было прикольно писать разработчику прямо в личную телегу).
До этого N работ назад использовали Crossbar.io, но когда я писал этот пост, обнаружил, что он уже при смерти.
А еще когда я смотрел альтернативы Centrifugo, то наткнулся на Server-sent Events (aka SSE, aka EventSource). Это стандарт для веба, который позволяет в одностороннем порядке слать уведомления. Рандомную демку можно посмотреть тут, работает даже с curl из коробки. В общем, жду светлые времена, когда в web-стандарте начнут поддерживать докер-контейнеры, чтобы там кубер свой запустить…
Переводчик Curl
Прикольный конвертер, который без смс и ChatGPT позволяет перевести Curl-запрос в код на одном из популярных языков. На мой взгляд, весьма полезно, так как в Curl любая помойка умеет экспортировать, а переписывать это руками лениво.
Работает не 100% идеально, но немного времени сэкономит. Мне пригодилось, чтобы пример из GitHub API перевести в питонячий код.
Вложенные куски кода в Markdown
Когда в GitHub пользовался функцией предложения изменений (классная штука, кстати) для файла Markdown, понадобилось вставить блок кода.
Выглядело это изначально так:
```suggestion
some words
```kotlin
some code
```
```
Парсер комментария от такого, разумеется, поломался: не понял, что первые ```
это конец блока кода, а не предложенного изменения. Оказалось, что у некоторых реализаций Markdown есть фича, что можно вместо трех обратных апострофов можно использовать 4 и больше. И тогда можно сделать так:
````suggestion
some words
```kotlin
some code
```
````
и все вложенные уровни распарсятся корректно. Разумеется, если посмотреть в исходники этого поста, то там тоже будет использоват этот же трюк.
Семантики памяти java
Неплохой, хоть и весьма специфичный доклад про то, какие есть варианты семантик в java, кроме happens-before: plain, opaque, acquire-release. В основном они нужны в случаях, когда гарантии от volatile
слишком сильные, и за счет использования более слабых семантик можно получить прирост производительности. Ну или если вы хотите унизить кого-нибудь на собесе, кто вам задает вопросы про многопоточность для вакансии перекладывателя json-ов.
В докладе обсуждается, что такое семантика вообще, кратко повторяется база, и показано иерархическое различие разных семантик. Ко всему есть наглядные примеры.
Вообще в этом контексте вспоминается более фундаментальная статья про модели памяти, о которой я писал ранее.
Вызов C++ из питона
Оказывается, кроме ctypes и Cython с тех пор как я смотрел появился еще один способ, pybind11 (если не считать всякие граали).
Но во всех трех подходах надо че-то думать: в ctypes надо код в динамическую библиотеку запихнуть, а потом ее еще и загрузить; в Cython надо немного поприседать с изменением исходников и типизацией; в pybind11 — писать экспорты.
Отрыл cppyy. В нем чтобы импортировать C++ класс достаточно написать
cppyy.include("someClass.cpp")
instance = cppyy.gbl.SomeClass()
… и все. Методы и классы легко грузятся по имени. Работает это все за счет cling — интерпретатора для C++. Можно грабить корованы создавать экземпляры стандартных классов, например, vector.
Разумеется, цена этому — производительность, но питон же, да и то, не все так просто.
Сравнение LLM
Занятное сравнение LLM. При этом методика очень простая: задать несколько вопросов чат ботам и сравнить ответы.
Меня порадовала задачка:
Sally (a girl) has 3 brothers. Each brother has 2 sisters. How many sisters does Sally have? Let’s think step by step.
Правильный ответ почти ни одна модель не смогла родить.