Blog

  1. Auto-Syncing Upstream Periodically to a Fork for Open-Source Contribution

    When using a fork to contribute to an open-source repo, it's useful for the fork's main branch to stay up to date with the upstream repository's main branch. For example, I contribute to VS Code, which merges hundreds of pull requests per week.

  2. Windows Terminal profile for Claude with no permission prompts

    Every time I open Claude Code in a new directory I get a workspace trust prompt asking me to approve permissions. It makes sense as a safety guardrail, but in directories I own and trust it's just friction. I made a dedicated Windows Terminal profile that launches Claude with --permission-mode bypassPermissions so it skips straight to work.

  3. Tailscale + SSH setup for Windows + WSL2

    I do a lot of work from my phone while away from my desk and wanted a clean way to SSH into my Windows machine and drop into whichever WSL2 distro I needed. The tricky part: iOS Tailscale intercepts port 22, WSL2 distros share a network namespace so you can't run independent sshd instances on the same port, and adding a Tailscale node per distro causes TUN device conflicts.

  4. How to limit the number of Twitter posts in your timeline using JavaScript

    I have a bit of a problem scrolling too much of the awesome content on Twitter. There are just too many other people creating cool ideas and software! At first I justified it by the fact that I find academic papers (my feed is curated to mostly academic CS/ML/SE), but now I admit it's too much! In a bid to waste more time in order to waste less time, I created a simple script that puts an extra UI onto each post in my Twitter feed: - For the first five posts, it numbers them to remind me how many I've browsed. - After that, it blocks them out with a reminder of the limit I set (currently I keep it at five posts).

  5. How to set up a shared cache for HuggingFace libraries

    My lab members and I use a shared machine to run, among other things, large language model inference using the transformers and datasets libraries. HuggingFace libraries download the model weights or datasets, and the downloaded files can be very large (over 50GB). By default, the weights and datasets are downloaded to some folders under /.cache/huggingface/. Different users will download copies of the same models. This causes the storage requirements to grow much larger than what is needed.

  6. How to fix docker-compose: command not found error with newer versions of Docker

    The docker-compose command is missing from recent versions of Docker, replaced by a plugin built into Docker: docker compose. To restore compatibility with scripts which use docker-compose, we can create a wrapper script which forwards its arguments to docker compose. Here's the script:

  7. How to use task-spooler as a shared queueing system

    I share a machine with several labmates. This machine has a single high-powered GPU which we share for our experiments. However, only one of us (usually) can use it at a time. This means that if someone else is running an experiment, I have to write down my command, wait for their experiment to be over (which can run several hours), get pinged by them, then check back when they're done and run by experiment. If I run my experiment without checking if the GPU is in-use, it can my program can experience an error, or worse, the other person's in-progress program may experience an error and they'll have to reset it. How can we efficiently run our experiments?

  8. friendship ended with earlyoom, now nohang is my best friend

    I used to use earlyoom to ensure that my desktop PC will still keep running if a program hogs all the memory (e.g. loading a too-large dataset into memory). I recently couldn't get earlyoom to work with Fedora 37, and while searching for a solution I found nohang. Here are some useful features of nohang which convinced me to switch:

  9. Siamese network and triplet loss

    Siamese network is an architecture which runs two networks with shared weights (effectively runs the same network twice) on two different inputs simultaneously. It is commonly trained with a contrastive loss such as triplet loss in order to draw together the representations of similar inputs and push apart the representations of contrasting inputs.

  10. Get filepath of Bash activation script

    Use ${BASHSOURCE[0]} to reference the filepath of a Bash script. Unlike $0, this works if the script is called via bash script.sh or source script.sh.

  11. webcam-mods for Linux background blur & swap

    webcam-mods is the best method I have found for webcam background blur/swap on Linux. I use this for my meetings on Google Meet and Webex.

  12. Beware any vs len

    I fell into the habit of using any() to check if a list is empty. It's nice because it works for any enumerable, including generators, even if len() is not defined. However, it has a pitfall where if the list is nonempty but contains only falsy values, any() returns False. For this reason, I advise to use len() to check if a list is empty.

  13. Use head -n -0 to get all items in list

    You may know that you can use head -n $n to get the first N lines of a list. But you may not know that you can supply n=-0 to get all items in the list.

  14. Use hard links to replicate log files in a generated directory

    Recently I wanted to write program logs to a file, then copy it to the directory where I store my checkpoints. Because I want to log things before I create the checkpoint directory, I attached my logger to a file in my root directory.

  15. Beware metric auto-reduce with PyTorch Lightning + TorchMetrics

    PyTorch Lightning + TorchMetrics can log metrics per step and per epoch. It also has MetricCollection, which can be used to compute several metrics at once, getting rid of redundant code. Here is how I have it set up:

  16. Print pandas Series as percent

    Use this snippet to print a pd.Series of floats as percentages.

  17. Encoder-decoder models

    Encoder decoder is a deep neural network architecture that consists of 2 components: - Encoder: input -> encoder memory (real-valued vector), - Decoder: encoder memory -> output. Input is variable length, encoder memory is fixed length.

  18. Print item keys with jq

    I can use jq to print the keys in an array of JSON objects quickly.

  19. Neural Network Embeddings

    Embeddings are used to map high-dimensional data to low-dimensional floating-point representation. This may improve the performance because it improves the representation of the input given to the model.

  20. Meditations on Meditations: I-IV

    I'm reading Marcus Aurelius's Meditations in Marcus Aurelius and His Times (Transition from Paganism to Christianity) [0].

  21. Programming problem: Gematria

    I've recently been studying history in the Bible by following along with the phenomenal podcast of the same name, History in the Bible by Garry Stevens. As part of his series, I learned about gematria, which is the ancient practice of assigning a number to a name based on the letters in the name.

  22. No pain no gain? Comparing 3 program analysis frameworks for C

    Program analysis methods often represent programs as graphs. These graphs should be automatically generated from the source code. There are many tools that have been implemented to do this, but they are often painful to set up. In this post, I will compare 3 program analysis frameworks which I have used to generate graph representations of C programs.