[{"content":"A collection of notes, links, posts.\n2026-07-10 # Catlantean 3D - Making Graphics Like It\u0026rsquo;s 1993 I wanted a camera that doesn’t exist — so I built it 2024-06-03 # The Big LLM Architecture Comparison 2024-06-03 # Reverse Engineering a Neural Network\u0026rsquo;s Clever Solution to Binary Addition A Mechanistic Interpretability Analysis of Grokking What We Learned from a Year of Building with LLMs (Part I) What We Learned from a Year of Building with LLMs (Part II) 2023-09-09 # Style your RSS feed The Erland Runtime System 2023-06-11 # m15o projets Doom engine code review 2023-05-07 # Most interesting tech you built for just yourself? Knowledge Retrieval Architecture for LLM’s (2023) Spycraft: The Great Game Bartosz Ciechanowski Bicycle 2023-04-08 # FastAI stable dissusion course Bridging the synchronization gap on Linux 2023-03-11 # Mars after midnight gameplay loop Ditherpunk Single File Elixir Scripts 2023-02-21 # What is ChatGPT doing and why does it work 2023-02-19 # home setup - v4.0 How I Replaced Dropbox with Rsync and Why 2023-02-04 # Ask HN: Those making $500+/month on side projects in 2023 – Show and tell 2023-01-26 # Hundreds of quant papers from #QuantLinkADay in 2022 2023-01-22 # Golang 1.20 changes Golang 1.20 changes part 2 2022-01-10 # Serverless Video Transcription inspired by Cyberpunk 207 2022-10-11 # How Wine works 101 2022-10-01 # GIFs Without the .gif: The Most Performant Image and Video Options Right Now 2022-09-17 # S3 glacier backup 2022-09-06 # 9front plan9port 2022-09-02 # fast.ai Practical Deep Learning 2022-08-24 # xit.nvim nvim plugin ","date":"10 July 2026","permalink":"https://blog.vladmykhailenko.com/notes/","section":"Vlad Mykhailenko","summary":"","title":"Notes"},{"content":"","date":null,"permalink":"https://blog.vladmykhailenko.com/","section":"Vlad Mykhailenko","summary":"","title":"Vlad Mykhailenko"},{"content":"Recently I have been experimenting with elixir machine learning. I decided to recreate fast.ai \u0026ldquo;bird or not\u0026rdquo; fine tuning tutorial. The language and the livebooks made it a very pleasant experience.\nThis post is a collection of notes about it.\nInitially I wanted to use EMLX to use MLX as a backend for NX. But I only managed to make it work for classification without fine tuning, so this is something I will try in the future. In chunk_every call I\u0026rsquo;m using discard to avoid doing additional padding of the training/testing data, as my datasets didn\u0026rsquo;t divide evenly. As model spec already had labels all I needed to do is override them with my own. The dataset already has all images sized to 224x224 so there is on need to resize them. In case your images are different you\u0026rsquo;ll need to Nx.reshape them or resize them. I spent a lot of time debugging only to find out the problem was the shape of image dataset stream that I was loading. It needs to be a batched stream. Livebook on github and dataset on huggingface\n","date":"20 January 2025","permalink":"https://blog.vladmykhailenko.com/posts/model-fine-tuning-with-elixir/","section":"Posts","summary":"","title":"Model Fine Tuning With Elixir"},{"content":"","date":null,"permalink":"https://blog.vladmykhailenko.com/posts/","section":"Posts","summary":"","title":"Posts"},{"content":"After using nvim \u0026ldquo;bundles\u0026rdquo; like NvChad, LunarVim for some time I decided to go through the list of plugins they use, decide what I need, and configure everything myself. When I use these bundles I am not familiar with the config and it can be hard to discover and tweak plugins. So if I need to go through the plugin documentation to see what it does and how it works I might as well configure everything myself. So in this post I\u0026rsquo;m going to document my Neovim configuration.\nEven though I don\u0026rsquo;t use vim as my main editor, learning it can be a very useful skill. I can bring vim keybindings to any editor (IDEA, VS Code, etc.) with plugins and other applications like browsers. At work I use Intelij IDEA with vim motions, and my goal was to have the same number basic features in vim. Here is the list.\nNo tabs - When using tabs I have to spend extra time to managing them (closing/reordering). Global fuzzy search. Quick switch between files/buffers. Auto complete. Nothing extraordinary really.\nPlugin list # Packer - plugin manager NvimTree - tree file explorer TreeSitter - source code highlighting Telescope - fuzzy file finder, buffer switcher lspconfig - configurations for lsps nvim-cmp - completion engine cmp-nvim-lsp nvim-snippy - snippet manager cmp-snippy Directory structure #. ├── init.lua ├── lua │ └── vladmyh │ ├── lspconfig.lua │ ├── nvim-tree.lua │ ├── nvimcmp.lua │ ├── telescope.lua │ └── treesitter.lua ├── plugin │ └── packer_compiled.lua ├── undodir └── ~ init.lua is the main configuration file. lua/vladmyh directory contains configuration files for plugins. The reason for another directory inside lua directory is to prevent namespace clashes between plugins. For example, if telescope plugin has a file named lua/telescope.lua it will be ambiguous which file to load. You can find more information about namespaces here.\nMain configuration #This is the main init.lua file. Neovim supports both vimscript and lua in configuration I chose lua. Here I have some helper functions, general settings and plugin declarations.\n-- Helpers function map(mode, shortcut, command) vim.api.nvim_set_keymap(mode, shortcut, command, { noremap = true, silent = true }) end function map_func(shortcut, command) vim.keymap.set(\u0026#39;n\u0026#39;, shortcut, command, { noremap = true, silent = true}) end local o = vim.o local wo = vim.wo local bo = vim.bo -- Settings vim.g.mapleader = \u0026#34; \u0026#34; o.ignorecase = true o.undodir = \u0026#39;~/.config/nvim/undodir\u0026#39; o.undofile = true o.smartcase = true o.splitbelow = true o.splitright = true o.scrolloff = 4 o.mouse = \u0026#39;a\u0026#39; o.relativenumber = true wo.number = true bo.tabstop = 4 bo.softtabstop = 4 bo.expandtab = true bo.smartindent = true -- Keys vim.g.mapleader = \u0026#39; \u0026#39; map(\u0026#39;n\u0026#39;, \u0026#39;\u0026lt;leader\u0026gt;j\u0026#39;, \u0026#39;:wincmd j\u0026lt;cr\u0026gt;\u0026#39;) map(\u0026#39;n\u0026#39;, \u0026#39;\u0026lt;leader\u0026gt;k\u0026#39;, \u0026#39;:wincmd k\u0026lt;cr\u0026gt;\u0026#39;) map(\u0026#39;n\u0026#39;, \u0026#39;\u0026lt;leader\u0026gt;h\u0026#39;, \u0026#39;:wincmd h\u0026lt;cr\u0026gt;\u0026#39;) map(\u0026#39;n\u0026#39;, \u0026#39;\u0026lt;leader\u0026gt;l\u0026#39;, \u0026#39;:wincmd l\u0026lt;cr\u0026gt;\u0026#39;) -- Plugins require(\u0026#39;packer\u0026#39;).startup(function() use { \u0026#39;kyazdani42/nvim-tree.lua\u0026#39;, requires = { \u0026#39;kyazdani42/nvim-web-devicons\u0026#39;, -- optional, for file icons } } use { \u0026#39;nvim-treesitter/nvim-treesitter\u0026#39;, run = \u0026#39;:TSUpdate\u0026#39; } use \u0026#39;nvim-treesitter/playground\u0026#39; use \u0026#39;neovim/nvim-lspconfig\u0026#39; use { \u0026#39;nvim-telescope/telescope.nvim\u0026#39;, requires = { {\u0026#39;nvim-lua/plenary.nvim\u0026#39;} } } use \u0026#39;hrsh7th/nvim-cmp\u0026#39; use \u0026#39;hrsh7th/cmp-nvim-lsp\u0026#39; use \u0026#39;dcampos/nvim-snippy\u0026#39; use \u0026#39;dcampos/cmp-snippy\u0026#39; use { \u0026#39;rose-pine/neovim\u0026#39;, as = \u0026#39;rose-pine\u0026#39;, config = function() vim.cmd(\u0026#39;colorscheme rose-pine\u0026#39;) end } end) require(\u0026#39;vladmyh/telescope\u0026#39;) require(\u0026#39;vladmyh/lspconfig\u0026#39;) require(\u0026#39;vladmyh/nvimcmp\u0026#39;) require(\u0026#39;vladmyh/treesitter\u0026#39;) require(\u0026#39;vladmyh/nvim-tree\u0026#39;) -- NvimTree map(\u0026#39;n\u0026#39;, \u0026#39;\u0026lt;leader\u0026gt;n\u0026#39;, \u0026#39;:NvimTreeToggle\u0026lt;cr\u0026gt;\u0026#39;) -- Telescope map(\u0026#39;n\u0026#39;, \u0026#39;\u0026lt;leader\u0026gt;ff\u0026#39;, \u0026#39;:Telescope find_files\u0026lt;cr\u0026gt;\u0026#39;) map(\u0026#39;n\u0026#39;, \u0026#39;\u0026lt;leader\u0026gt;fb\u0026#39;, \u0026#39;:Telescope buffers\u0026lt;cr\u0026gt;\u0026#39;) map(\u0026#39;n\u0026#39;, \u0026#39;\u0026lt;leader\u0026gt;fg\u0026#39;, \u0026#39;:Telescope git_files\u0026lt;cr\u0026gt;\u0026#39;) map(\u0026#39;n\u0026#39;, \u0026#39;\u0026lt;leader\u0026gt;fp\u0026#39;, \u0026#39;:Telescope grep_string\u0026lt;cr\u0026gt;\u0026#39;) LSP Config #Here we define a number of keybindings in the on_attach function, which is called only on buffers with active language server. It means that if I open a file that I do not have an lsp setup for the keybindings won\u0026rsquo;t be set. I use default keybindings and use map_func from main init.lua.\nmap_func(\u0026#39;\u0026lt;leader\u0026gt;e\u0026#39;, vim.diagnostic.open_float) --map_func(\u0026#39;\u0026lt;C-e\u0026gt;\u0026#39;, vim.diagnostic.open_float) map_func(\u0026#39;[d\u0026#39;, vim.diagnostic.goto_prev, opts) map_func(\u0026#39;]d\u0026#39;, vim.diagnostic.goto_next, opts) map_func(\u0026#39;\u0026lt;leader\u0026gt;q\u0026#39;, vim.diagnostic.setloclist, opts) local on_attach = function(client, bufnr) -- Enable completion triggered by \u0026lt;c-x\u0026gt;\u0026lt;c-o\u0026gt; vim.api.nvim_buf_set_option(bufnr, \u0026#39;omnifunc\u0026#39;, \u0026#39;v:lua.vim.lsp.omnifunc\u0026#39;) -- See `:help vim.lsp.*` for documentation on any of the below functions local bufopts = { noremap=true, silent=true, buffer=bufnr } map_func(\u0026#39;gD\u0026#39;, vim.lsp.buf.declaration, bufopts) map_func(\u0026#39;gd\u0026#39;, vim.lsp.buf.definition, bufopts) map_func(\u0026#39;K\u0026#39;, vim.lsp.buf.hover, bufopts) map_func(\u0026#39;gi\u0026#39;, vim.lsp.buf.implementation, bufopts map_func(\u0026#39;\u0026lt;C-k\u0026gt;\u0026#39;, vim.lsp.buf.signature_help, bufopts) map_func(\u0026#39;\u0026lt;leader\u0026gt;wa\u0026#39;, vim.lsp.buf.add_workspace_folder, bufopts) map_func(\u0026#39;\u0026lt;leader\u0026gt;wr\u0026#39;, vim.lsp.buf.remove_workspace_folder, bufopts) map_func(\u0026#39;\u0026lt;leader\u0026gt;wl\u0026#39;, function() print(vim.inspect(vim.lsp.buf.list_workspace_folders())) end, bufopts) map_func(\u0026#39;\u0026lt;leader\u0026gt;D\u0026#39;, vim.lsp.buf.type_definition, bufopts) map_func(\u0026#39;\u0026lt;leader\u0026gt;vrn\u0026#39;, vim.lsp.buf.rename, bufopts) map_func(\u0026#39;\u0026lt;leader\u0026gt;ca\u0026#39;, vim.lsp.buf.code_action, bufopts) map_func(\u0026#39;gr\u0026#39;, vim.lsp.buf.references, bufopts) map_func(\u0026#39;\u0026lt;leader\u0026gt;f\u0026#39;, vim.lsp.buf.formatting, bufopts) end -- -- Setup lspconfig. local capabilities = require(\u0026#39;cmp_nvim_lsp\u0026#39;).default_capabilities(vim.lsp.protocol.make_client_capabilities()) local lsp_flags = { -- This is the default in Nvim 0.7+ debounce_text_changes = 150, } require(\u0026#39;lspconfig\u0026#39;)[\u0026#39;gopls\u0026#39;].setup{ on_attach = on_attach, flags = lsp_flags, capabilities = capabilities } require(\u0026#39;lspconfig\u0026#39;)[\u0026#39;elixirls\u0026#39;].setup{ on_attach = on_attach, flags = lsp_flags, capabilities = capabilities, cmd = {\u0026#34;/usr/bin/elixir-ls\u0026#34;} } Nvim tree #require(\u0026#39;nvim-tree\u0026#39;).setup() Nvimcmp #local cmp = require(\u0026#39;cmp\u0026#39;) cmp.setup{ snippet = { expand = function(args) require(\u0026#39;snippy\u0026#39;).expand_snippet(args.body) end, }, window = { -- completion = cmp.config.window.bordered(), -- documentation = cmp.config.window.bordered(), }, mapping = cmp.mapping.preset.insert({ [\u0026#39;\u0026lt;C-b\u0026gt;\u0026#39;] = cmp.mapping.scroll_docs(-4), [\u0026#39;\u0026lt;C-f\u0026gt;\u0026#39;] = cmp.mapping.scroll_docs(4), [\u0026#39;\u0026lt;C-Space\u0026gt;\u0026#39;] = cmp.mapping.complete(), [\u0026#39;\u0026lt;C-e\u0026gt;\u0026#39;] = cmp.mapping.abort(), [\u0026#39;\u0026lt;CR\u0026gt;\u0026#39;] = cmp.mapping.confirm({ select = true }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items. }), sources = cmp.config.sources({ { name = \u0026#39;nvim_lsp\u0026#39; }, { name = \u0026#39;snippy\u0026#39; }, -- For snippy users. }, { { name = \u0026#39;buffer\u0026#39; }, }) } Telescope #Apart from key mappings I set property sort_mru to true to get the list of buffers from most recently used, and initial_mode to normal in order to set initial mode of buffer menu to normal mode. You can find parameter description here.\nrequire(\u0026#39;telescope\u0026#39;).setup { pickers = { buffers = { sort_mru = true, --sort buffers by mru initial_mode = \u0026#34;normal\u0026#34; --start buffer picker in normal mode } } } Treesitter #require\u0026#39;nvim-treesitter.configs\u0026#39;.setup { ensure_installed = { \u0026#39;lua\u0026#39;, \u0026#39;go\u0026#39;, \u0026#39;rust\u0026#39;, \u0026#39;elixir\u0026#39;, \u0026#39;erlang\u0026#39; }, sync_install = false, auto_install = true, highlight = { enable = true, additional_vim_regex_highlighting = false, }, } Useful motions #Here is the list of some useful motions that I try to add to my work.\nyap copy until newline down dap delete until newline down vap/kvap select down/up until new line va{ select until closing \u0026lsquo;}\u0026rsquo; (va(, va\u0026rsquo;, va\u0026quot;, etc.) o insert and edit line below, O line above I move to line start and edit A move to line end and edit VY copy whole line Ctrl + a increment number Ctrl + x decrement number Ctrl + v select multiple lines, I to go into edit mode '{'/'}' to jump between newlines ","date":"28 January 2023","permalink":"https://blog.vladmykhailenko.com/posts/my-nvim-setup/","section":"Posts","summary":"","title":"My Neovim Setup"},{"content":"In the beginning of the 2021 under the influence of my friend and /r/Homelab I decided to build a homeserver. I didn\u0026rsquo;t had any particular goal in mind other than excitment to tinker with some hardware and software, and also get more experience with some software infrastructure things that I usually don\u0026rsquo;t get to interact with. So in this post I will describe the hardware and the software that I run on my homelab server.\nBefore we start this is by no means the most optimal hardware/software configuration. All of this can be achieved on any hardware, or even something like Raspberry Pi.\nHardware #Here is the list of hardware I went with, apart from the ECC RAM everythings is pretty standard.\nMotherboard: Asus Prime B550-Plus\nCPU: AMD Ryzen 7 3800X\nRAM: Samsung 32 GB ECC DDR4 2666 MHz (M391A4G43MB1-CTD)\nSSD: Samsung 970 Evo series 500GB M.2 PCIe 3.0\nHDD: Western Digital Red Pro 2TB 7200rpm 64MB\nCase: Fractal Design Define R5 (I was also considering Silverstone GD07)\nCooler: Noctua NH-U12A\nPower Supply: Corsair RM650\nFor the CPU one of the main things I was looking for are the number of cores/threads, but also something that was available localy and something I could transfer to my gaming PC if things didn\u0026rsquo;t work out. As it turned out for the workloads that I run CPU load is pretty low, so lower end processor would have worked just as well.\nOne of the main reasons I went with AMD is ECC support. While it\u0026rsquo;s not something AMD advertises it\u0026rsquo;s supported on all their modern processors. As long as motherboard also supports it you should be good to go. I checked motherboard specs in order to make sure it supports RAM frequency and ECC. It is only unbuffered ECC that is supported for registered ECC you need to get Threadripper or EPYC.\nFor Intel you probably need to get Xenon for the EEC support you will have to check for yourself.\nAnd or course the CPU should support virtualization, which all modern processors should have. For Intel it\u0026rsquo;s VT-x, for AMD AMD-V.\nFor the case I was looking for reletively simple design and space for multiple hard drives in case I want to expand later. Define R5 can hold 2 SSDs and eight 3.5\u0026quot; HDDs which should be enough for me for a long time.\nSoftware #The server runs Proxmox an open-source software server for virtualization management. It has a very nice web interface to manage VMs. The setup was pretty straightforward and I didn\u0026rsquo;t encounter any problems in the long run with system updates and maintenance.\nThere are 4 VMs running:\nTrueNAS Nomad PostgreSQL Dev VM (there is also a pihole running on raspberry pi 3)\nTrueNAS #VM has 2 TB HDD passed through to it from ProxMox which it uses for storage. On top of it I have two plugins running.\nTransmission - torrent client that downloads torrents to TrueNAS.\nPLEX - A media server that lets you host your own media, it also streams from TrueNAS.\nNomad #Nomad is a workload orchestrator used to deploy and manage applications. I use it to deploy docker applications but it supports Podman, Java applicatinos, or even an arbitrary commands for tasks (docs). It is a simple single node setup without redundancy (don\u0026rsquo;t use it like this in production obviously).\nSome things that I run in Nomad:\nHeimdal - a nice dashboard to quickly access all services within my network.\nWireguard - VPN server I can connect to from outside my network. I got a static IP from my ISP to do it.\nNextCloud - a self-host cloud, I mostly use it for file storage and calendar. All data is stored on a NFS mount from TrueNAS that I mount to the nomad VM, and then add a docker volume.\nI also want to mention that before arriving on Nomad I tried both Kubernetes and Rancher. Kubernetes required too much management for me and Rancher broke during updates (and made me appreciate DevOps people even more), which obiously was my error but this is why I moved to Nomad. For my needs Nomad was perfect as it required minimal setup/maintenance, after all right now the server is a hobby project so I want to have a good balance between time I invest in it and results that I get back.\nPostgrSQL #Just a Debian VM with PostgreSQL running on it. I usually use it for side projects that run on Nomad.\nDev VM #This is something I\u0026rsquo;ve been testing, a vm with dev environment setup that I can access through Wireguard by SSH or RDP. I mostly do Java development with some Go on the side so all the software on it is pretty standard: jdk, go, git, Idea, Goland, nvim, jq.\nPlans for the future #Some things that I want to do in the future with my homelab:\nAdding monitoring and alerts to all services. Automating some repetative tasks with Ansible. RAID or ZFS mirrors. Getting domain name and hosting some services publicly. Generally improve security. Backups with rsync. Running Nomad cluster on Raspberry Pis, I\u0026rsquo;m planning to buy at least 3 Pis and move most services to them. ","date":"10 April 2022","permalink":"https://blog.vladmykhailenko.com/posts/my-home-server-setup/","section":"Posts","summary":"","title":"My Home Server Setup"},{"content":"","date":null,"permalink":"https://blog.vladmykhailenko.com/categories/","section":"Categories","summary":"","title":"Categories"},{"content":"","date":null,"permalink":"https://blog.vladmykhailenko.com/tags/","section":"Tags","summary":"","title":"Tags"}]