About Garrit Franke

The RSS's url is : https://garrit.xyz/rss.xml

Please copy to your reader or subscribe it with :

Preview of RSS feed of Garrit Franke

🔗 Linkdump: LLMs

2024-07-02 08:00:00

The more I'm getting into large language models (LLMs), the more I'm fascinated about what you can do with them. To "digest" my reading list of cool articles and projects regarding LLMs, I assembled the following list. If you're also interested but haven't started your journey into this neverending rabbit hole, these may contain some good pointers:

Running LLMs

Building Chatbots & Applications

Training and finetuning

Miscellaneous projects

Blogs

Testing SMTP connections

2024-06-27 08:00:00

Just a quick note to my future self on how to test a SMTP connection with nothing but a tiny busybox container.

In my case specifically, I tested the connection from inside a Kubernetes cluster. Here's the quickest way to get a temporary pod up and running:

kubectl run -n backend -i --tty --rm debug --image=busybox --restart=Never

Busybox comes with telnet installed, which we can use to establish a connection to the server:

/ # telnet smtp.mydomain.com 25 Connected to smtp.mydomain.com 220 mail.mydomain.com ESMTP Postfix (SMTP)

Next, we can issue the SMTP commands through the open TCP connection to send a test mail. Lines beginning with a status code are server responses:

` HELO smtp.mydomain.com 250 smtp.mydomain.com MAIL FROM:[email protected]
250 2.1.0 Ok RCPT TO:[email protected] 250 2.1.5 Ok DATA
354 End data with <CR><LF>.<CR><LF> From: [noreply] [email protected] To: [Receiver] [email protected] Date: Thu, 27 Jun 2024 10:08:26 -0200 Subject: Test Message

This is a test message.

. 250 2.0.0 Ok: queued as 2478B7F135 `

In case there's a firewall issue, you might not be able to establish a connection in the first place, or you won't get a reply to your TCP commands. In our case, everything worked fine.

I hope this is useful!

Host your own LLM

2024-06-17 08:00:00

I'm currently dipping my toes into Large Language Models (LLMs, or "AI") and what you can do with them. It's a fascinating topic, so expect some more posts on this in the coming days and weeks.

For starters, I wanted to document how I got my first LLM running on my local machine (a 2022 MacBook Pro). Ollama makes this process super easy. You just install it (brew install ollama in my case) and then run the model:

ollama run llama3

This will download the model and open a prompt, so you can start chatting right away!

You can think of Ollama as the Docker CLI but for LLMs. There's a directory of LLMs, and if a model has multiple different sizes, you can use it like you would pull a different docker tag:

ollama pull llama3:8b ollama pull llama3:70b

The best thing about ollama is that it also exposes a web server for you to integrate the LLM into your application. As an example, here's how you would curl your local LLM:

curl http://localhost:11434/api/chat -d '{ "model": "llama3", "messages": [{ "role": "user", "content": "Are you a robot?" }], "stream": false }' {"model":"llama3","created_at":"2024-06-17T11:19:23.510588Z","message":{"role":"assistant","content":"I am not a human, but I'm also not a traditional robot. I'm an artificial intelligence language model designed to simulate conversation and answer questions to the best of my ability. My \"brain\" is a complex algorithm that processes natural language inputs and generates responses based on patterns and associations learned from large datasets.\n\nWhile I don't have a physical body or consciousness like humans do, I'm designed to interact with humans in a way that feels natural and conversational. I can understand and respond to questions, make suggestions, and even tell jokes (though my humor may be a bit... algorithmic).\n\nSo, while I'm not a human or a traditional robot, I exist at the intersection of technology and language, designed to assist and communicate with humans in a helpful way!"},"done_reason":"stop","done":true,"total_duration":12565842250,"load_duration":7059262291,"prompt_eval_count":15,"prompt_eval_duration":331275000,"eval_count":156,"eval_duration":5172858000}

If your local machine is not beefy enough and you want to try out a large LLM on a rented server (AWS has g5.2xlarge, which gave me good results for mixtral 8x7b), you also have to set OLLAMA_HOST=0.0.0.0 in your environment variables to be able to reach the remote server. This exposes the LLM to the public internet, so be careful when chosing your deployment strategy.

And there you go! You just deployed your very own LLM. Pretty cool, huh?

I just cleaned up 40 GB of Brew caches

2024-06-03 08:00:00

EDIT: This trick will probably not be as effective on your system as it was on my system. After writing this post I realized that I had the HOMEBREW_NO_INSTALL_CLEANUP=1 flag enabled on my system.

My system (MacOS) is getting more cluttered the more I use it. I'm sure you can relate. If you're using Brew as your package manager (which you should 😉), you might want to consider running the following command:

brew cleanup -s

For some reason this failed after some time with a "directory not found" error, but you can just run it again and it will continue cleaning up old caches. Once it was done, this freed up 40 GB of disk space on my system. It might make sense to run this as a cronjob? Either way, I just wanted to jot this down before I enevitably forget this, as usual.

Going from self hosted to managed software

2024-05-24 08:00:00

Some time ago I was heavily into self hosting my own software. Over time though, it became apparent that maintaining these services is a huge burden. I either abandoned most of the services or found a replacement that suits my needs and saves me time that's better spent on other things in life.

Today, I finally pulled the plug on Miniflux, the last service I used to self host (not counting House Assistant on a Pi, which I use to automate some stuff at home). The Hetzner server it ran on cost me ~4€ a month. The maintainer of Miniflux offers a managed hosting solution for 15$ a year, so to save money and time, and to support the project, I decided to switch from self-hosted to managed.

Will I ever self host again?

I really don't know. Some services (Miniflux included) required very little maintenance to keep running, so I could see myself spinning up a server again if I really wanted to run some software that doesn't have managed hosting. For now though, I'm planning on using managed services wherever I can. Nevertheless I'm proud of the things I learned during my time of self hosting my software. I think it gave me a huge boost both in terms of know how and my career, and I'd encourage everyone to dip a toe into self hosting.

About my 'smart' G-Shock

2024-05-10 08:00:00

About two weeks ago, I got myself my very first G-Shock. My entry ticket to the #CasioCult! Since I didn't want to miss out on any fitness features, I went with the G-Shock GW-H5600, which comes with heart rate monitoring, step tracking and some other nice to have features.

A G-Shock DW-H5600

Having read every review I could find, I knew that the watch had some quirks, but I ultimately loved the look of it. But two weeks later, I'm forced to return the watch. Let me first go over what I liked and dislike about this watch.

Pros

It's a G-Shock

I love the look and feel of a G-Shock and other Casio watches. This is my first G-Shock, but I've had an eye on this brand for quite some time. It's tough, sturdy, waterproof and probably also bullet proof.

The display

Oh, the display! It's gorgeous. Many people are complaining why this MIP display hasn't found its way to the rest of the G-Shock lineup. But I'm sure they will retrofit other models soon.

Proper paper manual

My first impression after the unboxing was "holy sheers, the manual is a book"! And I mean that in the best way possible. Every little feature of the watch is explained in extreme detail in the manual. You rarely see this in other watches or gadgets these days.

Cons

Questionable UI and UX decisions

G-Shocks are known for user interfaces that "just work". In this watch however, there are a few things that really make the watch frustrating to operate. Just to name a few quirks:

A bit thick

Below the already thick bezel of the G-Shock sits the heart rate monitor, which is obnoxiously huge. I personally didn't feel like it irritated my skin, but it does add to the thickness.

Fitness Features

This is a two-edged sword. I originally wanted to list this as a pro. Features like run tracking, cardio status and sleep analysis are there, and they work fine. The step tracking and heart rate monitoring can be a bit off from time to time, but it's fine for the occasional run.

What's really bothering me is the mediocre implementation. There's no workout detection, the autopause feature barely works and you're limited to running, walking, gym workout and interval training. I also want to log my bike rides, which will always show up as a running activity in my app.

They recently added Strava integration, which sort of works. The data is all there, but for some reason the pace and moving time that Strava computes are completely off. For example, I ran 55 minutes straight with an average pace of 9 minutes / km. But with the data the watch sends, Strava thinks I only moved for 26 minutes with a pace of 4 minutes / km. If that were true, I could compete in the olympics! 😅

Notifications barely work

During the time I owned the watch, there was only one random day where the watch received notifications from my phone. I can't explain why, but I just didn't get this to work properly.

Case is not screwed in. Could fall off

This is just a minor thing if you really care about durability. All G-Shock squares so far had screwed in bezels. On this model, you can pull off the bezel with enough force. I've never done it, but losing the bezel might be a concern.

What's next?

I enjoyed my time with this watch, but I filed a return. As pretty as the watch is, it is just too frustrating to use. Smart watches aren't a core part of Casio's business, and you can feel that in the lack of quality of the software. The app was likely developed as a one-off contract by some random agency, and once the contract ends, the watch won't ever be improved again.

I've now ordered the Garmin Instinct 2S Solar, which is very similar in terms of specs. MIP display, top-up solar charging, long-lasting battery and fitness features. But on top of that, it has features like music control, GPS, contactless payment and a compass. Contrary to Casio, Smartwatches are a core part of Garmin's business, which makes me believe that they go out of their way to develop the best possible watch they can. I will likely follow up with how this new watch compares to my G-Shock.

I sold my car

2024-05-08 08:00:00

I grew up in the countryside, where busses only came once an hour, but only until 7 PM. And on the weekend, you really had to plan ahead. Living without a car was almost unthinkable.

My car

After moving to the city in 2020, I found that I used my car less and less. My commute to work was easier with the bike (if I wasn't working from home), and for anything else, busses and trams were the way to go. The occasional family visit was the only excuse to use my car.

Owning a car doesn't "feel" expensive. Sure, gas is expensive, but simply owning one doesn't feel like a huge burden on your wallet. Just to get a rough estimate, I jotted down all running costs.

Running costs

My car costs over 1000€ per year, or about 85€ per month, just to be moved about twice a month! So, a few weeks ago, I decided to sell it.

I created a posting on Kleinanzeigen (a german descendant of - and previously owned by - eBay), and after about two weeks, the car had a new owner. I hope that it's in better hands now and lives on to be a happy and frequently used car.

Going forward, I'm not worried about my mobility at all. My partner still owns her car and has the option to take the bus to work. So, if we're not on the road together, I can always fall back to using her car. And if she needs her car and I'm desperate to go somewhere afar, there's also multiple ride-sharing options available in my town. They are a bit expensive to use, but spending 40€ for a day trip to my family every two months is still way less than paying 85€ a month for a car that's sitting there idle.

Beware of base64 encoded strings

2024-04-15 08:00:00

I just encountered a fun little bug that I thought is worth sharing.

TL;DR: the base64 util breaks lines after a certain number of columns. Use a flag to specify "don't break". Here's the commit that fixes the issue:

<img width="1588" alt="image (3)" src="https://github.com/garritfra/garrit.xyz/assets/32395585/dba76692-c89f-44da-b70a-f6732a406d75">

It started when we noticed that a cronjob that used wget to regularly call an endpoint failed on one specific environment. The endpoint uses Basic Auth, which is essentially a header with a Base64 encoded representation of a username and password. Curl has this functionality built in, but to keep the attack surface as small as possible, we decided to stick to wget, which is part of busybox, to keep the container image size under 1 MB (!). After all, all we want to do is ping an endpoint.

This is the command we used up to this point:

wget --post-data="" -O - --header="Authorization: Basic $(echo -n $BASIC_AUTH_USERNAME:$BASIC_AUTH_PASSWORD | base64)" http://endpoint:8080/v1/cache

We noticed that the request worked fine on non-prod environments, but it failed on production with the following error:

The HTTP header line [b2verlk1rwjsnutbcapkjh==] does not conform to RFC 7230. The request has been rejected.

After digging around for a while and separating out the individual pieces of the commands, I noticed that the subcommand to build the header value (echo -n $BASIC_AUTH_USERNAME:$BASIC_AUTH_PASSWORD | base64) behaved differently on prod vs. non-prod. The password on prod is way longer compared to the other environments. Let's run this command with a short input:

sh / $ echo -n someuser:somepassword | base64 c29tZXVzZXI6c29tZXBhc3N3b3Jk / $

And again with a long input:

sh / $ echo -n someuser:somepasswordthatswaylongerthanthefirstonebutalsoverysecureandsafe | base64 c29tZXVzZXI6c29tZXBhc3N3b3JkdGhhdHN3YXlsb25nZXJ0aGFudGhlZmlyc3RvbmVidXRhbHNv dmVyeXNlY3VyZWFuZHNhZmU= / $

Bingo! There's a rogue newline character in the output of base64. The fix is very straight-forward. Using the -w0 flag for base64, we can force the output to be on the same line:

/ $ echo -n someuser:somepasswordthatswaylongerthanthefirstonebutalsoverysecureandsafe | base64 -w0 c29tZXVzZXI6c29tZXBhc3N3b3JkdGhhdHN3YXlsb25nZXJ0aGFudGhlZmlyc3RvbmVidXRhbHNvdmVyeXNlY3VyZWFuZHNhZmU=

This eventually fixed the issue. Not something I would've ever thought of!

A simple search bar

2024-04-11 08:00:00

I just added a simple search bar to my "More ..." page. It just redirects to a DuckDuckGo search with your search term and limits it to my site. Simple, yet effective!

The inspiration for this feature came from Salvatore Mesoraca's site. Here's the snippet, feel free to steal it:

jsx <form className="search" method="get" action="https://duckduckgo.com/" target="_blank"> <input id="search" type="search" name="q" placeholder="Search via DDG" /> <input type="hidden" name="sites" value="garrit.xyz" /> <input type="submit" value="Search" /> </form>

Try it out

Try searching for anything!

<form className="search" method="get" action="https://duckduckgo.com/" target="_blank"> <input id="search" type="search" name="q" placeholder="Search via DDG" /> <input type="hidden" name="sites" value="garrit.xyz" /> <input type="submit" value="Search" /> </form>

Beating Elden Ring

2024-04-10 08:00:00

⚠️ WARNING ⚠️: This post contains a lot of spoilers for the game Elden Ring.

So, I just beat Elden Ring. It took me 120 hours and, coincidentally, I was level 120 when I beat the final boss. That damn final boss... but more on that later.

Elden Ring won me over instantly, even though I've never played any of the other Souls games. After beating Breath of the Wild, I called it my favorite game. I just needed more games like this. When Elden Ring came out, people compared The Lands Between to the open world of Hyrule, and I quickly agreed. The freedom these games give you is absolutely unbeaten. You almost never really get "stuck" on something. You can always wonder off and explore until you're ready to take on the fight.

After about 50 hours into playing Elden Ring, I kind of lost my focus and stopped playing for a while. It was too huge of a game to beat at the time, so I gave up.

But then, Tears of the Kingdom came out and doubled up on the world of Hyrule. I absolutely adored this game. I spent day and night playing until I finally beat it. This game also motivated me to beat Elden Ring one more time. Despite failing over and over, each play session gave me a feeling of progression. I might not have beaten a boss yet, but there was always something happening the side that got me closer to beating it. Be it exploring and getting better gear or learning as much as I can about a boss to find ways to deal damange, I always got a small step closer to my goal. I'd go as far as to say I never felt so determined to reach a goal ever before in my life.

The boss fights in Elden Ring are obviously extremely difficult, but they're always fair. The bosses in this game never make mistakes, you're the one that screwed up. You just keep failing and failing, but with each run, you learn something new about the fight that makes it easier in the next run. And when you finally overcoming this challenge gives you a feeling of accomplishment like nothing else could.

What I didn't realize in the beginning of my playthough is how extremely well rounded the world and the lore of this game is. I spent days and nights indulging myself in the lore through numerous YouTube videos, guides and Wikis. Only then did I begin to understand the scale of this game. Every action of each character, every building and every item fits in the grand scheme of the world.

Going out of this, the biggest thing that stuck with me is the determination. Failing is part of your life, and that is okay. No matter how daunting a task is, there's always a way to overcome it. The Elden Beast is the final boss of the game, and it's also where I spent about a quarter of my playtime. This thing has absurd attacks, immense health, and did I mention that you have to beat it after beating another extremely difficult boss, without being able to top up your health? This fight is ridiculous. I spent multiple weeks trying to beat it. I was really close to giving up, but as I mentioned earlier, each run gets you a tiny bit closer to the finish line, so I pushed through. I refined my build, I leveled up my stats and I learned how to dance with the beast. Eventually, I won the fight not by luck, but by determination. I now feel like I understand every attack well enough to dodge it. My mind was on autopilot when I beat it.

Knowing this much about a game didn't teach me any practical skills. There's nothing I can do now that I couldn't do before I knew that Rykard (Lord of Blasphemy), son of Rennala and Radagon (also known as Queen Marika), chose to go against the Erdtree and eventually fed himself to a serpent to devour the entire world (which you prevented). But there's something about this game that left me craving for more. It's truly a masterpiece.

Bonus

In case you're interested, I uploaded some of the bossfights during my playthrough in this YouTube playlist:

<iframe width="560" height="315" src="https://www.youtube.com/embed/videoseries?si=j1Ue2lrrLy1JTOM9&amp;list=PLS8TKBZz1x5S6ojf24SMF1h_HYb4AyTxc" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>