Alcides Fonseca

40.197958, -8.408312

Uv as the sane Python packaging default

There are two main issues with python’s packaging tooling: There is no sane way to distribute python-written apps, in a way that guarantees that all dependencies (including C and Fortran-written OS-level dependencies) and a way to manage the dependencies of your python apps.

In particular, in-the-wild requirements.pip are neither OS-aware neither python-version aware. Maybe with Python 3.9 I want a set of dependencies, and with Python 3.13 I want another. This becomes relevant when dealing with multiple (api-breaking) numpy and other scientific packages.

Astral released a new uv version that tries to solidify the ecosystem, replacing all the usual, incomplete suspects (poetry, pip-tools, etc..). Their newish goal with uv is to become Python’s cargo. With uv, you can now create and run projects, execute standalone python tools on your OS (replacing pipx) and managing different python versions.

But one of my favorite features is the support for PEP 723, which allows you to include dependencies in single-file python scripts:

#!/usr/bin/env uv run
# /// script
# requires-python = ">=3.12"
# dependencies = [
#     "flask==3.*",
# ]
# ///
import flask
# ...

(via Simon Willison)

Rust Low-level Concurrency in Practice

Mara Bos and O’REILLY have made Rust Atomics and Locks available online for free.

If the only thing you need is to create threads to handle different tasks that share no state, you won’t need this. But if you ware working on shared data-structures among threads, this books provides a full reference with examples that will help you step to the next level in Rust. Highly recommend!

I might even use this book to revamp my “Parallel and Concurrent Programming” master-level course.

Scope of Generics in Python

Thanks to Continuous Integration, I have found a typing problem in our genetic engine program synthesis framework. It boiled down to me not defining a scope for a type variable.

I started with some code that looked like the following:

with the following error:

main.py:18: error: Argument 1 has incompatible type "P@consume"; expected "P@__init__"  [arg-type]
Found 1 error in 1 file (checked 1 source file)

You can load this example on the MyPy playground if you want to play around with it.

In this case, MyPy is inferring the type of data as dict[str, Callable[[P@__init__], bool], where the key is the init part of the type variable that ends up being different than the use o P inside the consume function. This behavior is because type vars are, by default, bound to the function/method, and not the class. The first step is to actually introduce the explicit annotation for data with the dict[str, Callable[[P],bool]] type, inside Subclass. Now we get a different error:

main.py:17: error: Dict entry 0 has incompatible type "str": "Callable[[P@__init__], bool]"; expected "str": "Callable[[P], bool]" [dict-item]

Now the P type variable in the field annotation is different than the ones inside the method. To actually bind the type variable to the whole class, we need to extend Generic[P]:

Now, we have no typing errors, and we do not even need the explicit type declaration for data.

Most of this issue was due to me not clearly understanding the default behaviors of type variables1. Luckily, if you are able to only support Python 3.12 and upwards, you can use the new, saner syntax. And maybe someday I’ll finish the draft post where I explain why Python’s approach to typing is the best (for prototyping type systems and meta-programming techniques, like we do in GeneticEngine) and the worst (for real-world use).

1 Who the hell creates a type variable through the definition of a variable??

Software Bill of Materials (in Rust)

Ferrous Systems has been hired to improve the state of SBOM (Software Bill of Materials) in Rust.

What is an SBOM and why is it important? A Software Bill of Materials (or SBOM) declares, among other things, the inventory of all components used to build the software artifacts, as part of the software supply chain. Using this information can help detect vulnerability / security issues with the software or determine all conflicts in used licenses. A major reason to provide SBOMs for software in Germany is that the Federal Office for Information Security highly recommends them as part of their technical guidelines for Cyber Resilience (see PDF for details).

In recent years a number of pieces of legislations have been passed to improve cybersecurity. For example the US issued an Executive Order on improving the Nation’s Cybersecurity. In Europe, the EU has proposed the Cyber Resilience Act to improve cybersecurity and cyber resilience. These efforts are in response to an increased number of cyber attacks in recent years.

Not that most companies care, but verifying the compatibility of the software licenses in all dependencies of your project should be a one command task. Furthermore, high-risk projects should vendor all their dependencies, and keep track of the progress of their dependencies. Which is rarely accounted when budgeting for a new software project.

SPECIES Scholarships 2024

SPECIES is a society that aims to promote evolutionary algorithmic thinking, most known for organising Evo*. They also have a scholarship program that allows students (and recent PhD graduates) to spend 3 months doing an internship at selected host institutions.

It just happens that I was accepted as an host institution. So if you are interested in Program Synthesis, in particularly exploring type systems to make synthesis more efficient, or using heuristic methods to scale type-driven synthesis (à lá synquid or Idris), consider applying!

Also, feel free to reach out to me if you need more details. I’m quite flexible in regards to the logistics.

Trackmania and Machine Learning

I’m not that into video games — I can use one hand the games I actually played and appreciated —, but one of those is Trackmania. You have a car, and you just use the four arrows to make it to the end of the hotwheelesque, loop-filled stadium-sized track.

Now if you are into machine learning, self-driving cars, David and Felipe just posted a wonderful survey about the history of ML in Trackmania. While real-world self-driving cars take all the attention, there is much you can study with just a compute game.

Visualisation of Proofs in Lean

Awesome video explaining an interesting hack to visualize with smooth animations the different steps in lean proofs.

Network being dropped on a ASUS Strix X670OE-E motherboard

So I found some logs that the network PCIe device was being dropped in Ubuntu 22.04.

igc (...) eno1: PCIe link lost, device now detached

After looking it up, I reached the conclusion that that particular chip overheats, which causes the kernel to drop the device.

Other than adding a heatsink, the solution is to change the OS configuration, so you make it slower, so it doesn’t overhead:

  • Adding these two kernel parameters: pcie_port_pm=off pcie_aspm.policy=performance
  • Disabling a bunch of TCP features: sudo ethtool --offload eno1 rx off tx off. I personally find this option a bit scary, so I ended up reversing it.

Functional Programming in Python 3.12

Oskar Wickström shows off recent Python features (generics + pattern matching) that make writing Python more similar to ML, Haskell, Rust or Scala. If you need to support old versions of Python, you will have to wait a couple years before you use proper generics syntax (although you can use the TypeVar class).


def print_tree[T](tree: RoseTree[T]):
    trees = [(tree, 0)]
    while trees:
        match trees.pop(0):
            case Branch(branches), level:
                print(" " * level * 2 + "*")
                trees = [(branch, level + 1) for branch in branches] + trees
            case Leaf(value), level:
                print(" " * level * 2 + "- " + repr(value))

Statically Typed Functional Programming with Python 3.12

Improve file transfer speed between Macs and Synology

To improve the file transfer speed between macOS and Synology, you should do the following:

  • On Synology, go to Control Panel/File Services/SMB and under Advanced Settings upgrade the minimum SMB version from 1 to 2. This might prevent old devices from connecting, but can improve the speed of modern devices.
  • On macOS, disable packet signing.

The Alternative Implementation Problem

Hopefully, at this point, you see where I’m going with this. What I’ve concluded, based on experience, is that positioning your project as an alternative implementation of something is a losing proposition. It doesn’t matter how smart you are. It doesn’t matter how hard you work. The problem is, when you build an alternative implementation, you’ve made yourself subject to the whims of the canonical implementation. They have control over the direction of the project, and all you can do is try to keep up. In the case of JITted implementations of traditionally interpreted languages, there’s a bit of a weird dynamic, because it’s much faster to implement new features in an interpreter. The implementers of the canonical implementation may see you as competition they are trying to outrun. You may be stuck trying to ice skate uphill.

Maxime Chevalier-Boisvert

This is surely true in Python or Lua, but I believe it might not necessarily be the case for Java (where there is a specification, and enough effort by the industry to create alternative implementations). But I agree in general, unless you have something unique (like Android support, despite Dalvik being stuck on Java 8 for ages), which both IronPython and Jython didn’t have — I guess there is no general need for accessing the .NET and JVM runtimes from dynamic languages.

ChatGPT in Papers

Google Scholar for certainly, here is turns up a huge number of academic papers that include parts that were evidently written by ChatGPT—sections that start with “Certainly, here is a concise summary of the provided sections:” are a dead giveaway.

Simon Willison

Peer review isn’t built to handle the flood of AI content, especially as not all of it will be obvious, and not all will be malicious (lots of scholars pay editors to help make their writing better, now they will use chat).

Ethan Mollick

Misha Teplitskiy

The AI boom will soon crash

Put in the simplest way: Things have been too good for too long in InvestorWorld: low interest, high profits, the unending rocket rise of the Big-Tech sector, now with AI afterburners. Wile E. Coyote hasn’t actually run off the edge of the cliff yet, but there are just way more ways for things to go wrong than right in the immediate future.

Money Bubble by Tim Bray

Tim (correctly) points out that when investors throw money at things that are not well understood (.com, web2.0, blockchain, AI), it will eventually disappoint and crash the markets. Enjoy it while you can.

Mamba: The Easy Way

Today, basically any language model you can name is a Transformer model. OpenAI’s ChatGPT, Google’s Gemini, and GitHub’s Copilot are all powered by Transformers, to name a few. However, Transformers suffer from a fundamental flaw: they are powered by Attention, which scales quadratically with sequence length. Simply put, for quick exchanges (asking ChatGPT to tell a joke), this is fine. But for queries that require lots of words (asking ChatGPT to summarize a 100-page document), Transformers can become prohibitively slow. […] Mamba appears to outperform similarly-sized Transformers while scaling linearly with sequence length.

Mamba: The Easy Way, by Jack Cook

A wonderful explanation of the architectural differences in mamba and how it is much faster than existing transformer implementations. May require some CNN/RNN background to fully understand.

Power Metal Data Analysis

Bands from Spain, Germany and Finland have an average of more than 1600 words vocabulary; in comparison native countries like UK, US and Scotland have an average of 925, 1383 and 1501 words respectively, The most metal words are deliverance, defender, honour, forevermore, realm and the least are shit, baby, fuck, girl, verse. The most negative song is Condemned To Hell by Gamma Ray and the most positive There’s Something In The Skies by Dark Moor.

Power Metal: is it really about dragons? by Matt D.

I really wish there was code available, because I think the 58 bands provide a quite limited dataset, and I’m curious about my own Power Metal collection.

Bloom Filters Explained

While this looks almost identical to a Set, there are some key differences. Bloom filters are what’s called a probabalistic data structure. Where a Set can give you a concrete “yes” or “no” answer when you call contains, a bloom filter can’t. Bloom filters can give definite “no“s, but they can’t be certain about “yes.”

Bloom Filters by Sam Rose

Setting up SLURM for Single-Node usage in Ubuntu 22.04

SLURM is one of the most popular schedulers for clusters and High-Performance Computing (HPC). It takes care of two tasks. Firstly, it prevents everyone from starting processes on the same machine in a way that none of the processes can run successfully (due to not enough RAM, Disk or CPU time). Secondly, it allows to submit a set of programs to multiple computers automatically.

Typically, SLURM is used in a single, weaker computer (called the login node). Users submit jobs (a single program that can be executed many times, in parallel) and these jobs are scheduled in more power machines, which the user has no access to (for consistency sake).

These instructions are for the case where you want SLURM controlling a single computer (node). This is useful when you do not have a cluster, but a single powerful machine. Many of the instructions are taken from How to quickly set up Slurm on Ubuntu 20.04 for single node workload scheduling.

Install SLURM

sudo apt update -y
sudo apt install slurmd slurmctld -y
sudo mkdir /etc/slurm-llnl/
sudo chmod 777 /etc/slurm-llnl
sudo mkdir /var/lib/slurm-llnl/
sudo mkdir /var/log/slurm-llnl/
sudo chmod 777 /var/lib/slurm-llnl/
sudo chmod 777 /var/log/slurm-llnl/

And update the permissions to your liking.
Then we need to create two files: /etc/slurm-llnl/slurm.conf and /etc/slurm/slurm.conf. They should be the same, but they are in two different locations because of the multimode support (not in use in our scenario). As such, I end up creating a soft link between the two:

sudo ln -s /etc/slurm-llnl/slurm.conf /etc/slurm/slurm.conf

Now we edit the contents of /etc/slurm/slurm.conf and of /etc/slurm/gres.conf to the following:

To fill in the last line of slurm.conf, you can run: slurmd -C

Note that this configuration sets up two Nvidia A30 GPUs. If you have no Nvidia GPUs, then you can delete gres.conf and remove Gres=gpu:2,mps:200 from slurm.conf.

Now you can start the slurm processes (one to manage the execution, the other to manage the queues):

sudo service slurmctld restart && sudo service slurmd restart

To troubleshoot, you should check the following files: /var/log/slurm-llnl/slurmd.log and /var/log/slurm-llnl/slurmctld.log.

The European AI act, and how to ensure properties of AI?

During my current visit to UCL’s SOLAR group, I attended this week’s SSE Seminar on the challenges posed by the AI Act, presented by Paolo Falcarin.

The European Union Artificial Intelligence act is EU’s first attempt of regulating AI products and services. It defines different requirements based on the risk level of the application (ranges between high, medium and low).

In particular, high-risk usage (healthcare, toys, security, …) have stricter requirements. To begin with, they need to be registered in an European database, and frequently updated as the implementation or requirements change. Furthermore, the service or product should be documented, should be traceable, transparent, secure and overridable by humans. Despite these requirements, there is no clear definition, or path forward on how these properties can be ensured, especially when applications are closed-source and frequently trained and updated. One of the challenges we addressed in CAMELOT was how to build interprable Machine Learning models. We explored the use of Genetic Programming and Domain-Specific Languages to create inherently interpretable models. My research team is continuing exploring that possibility.

General-Purpose models have a special categorization within the AI act: Providers of general-purpose models (think OpenAI or Google) must provide a good understanding of the capabilities and limitations, comply with European copyright law, and provide a sufficiently detailed summary about the content used for training of the general-purpose model, following a given template.

Despite all the effort in understanding the potential of deep neural networks, and generative models in particular, it is not clear year what exactly are the capabilities or limitations of what they can produce. Without a clear standard of what is expected, organizations might be able to completely ignore this requirement.

As an example, take the Gandalf AI game, in which you can (easily) trick the LLM into telling you the password of the next level, even though it was instructed not to. Even with the aditional blocks introduced by each level, it is still easy to win the game. This is the state of the art in protecting LLMs from producing a known output. On a larger scale, an earlier version of Microsoft’s AI-powered Bing also generated output that went against the policies it was purposely trained against.

As for the copyright compliance, this goes in direct conflict with what OpenAI is defending. In fact, using copyrighted materials for free in the context of learning is allowed by European law. As such, it is not clear what this article entails in practice. My guess is that this is going to require a reform on the copyright law, possible to distinguish human versus automated learning. Otherwise, models this efficient may never (legally) exist again. This is something the law and computer science communities should debate before politicians take the initiative.

Finally, general-purpose AI with systemic risks (probably all of Large Language Models) have stricter restrictions: they need to evaluate models based on standardised protocols and tools, documenting adversarial testing of the model. While there are good practices for evaluating models, I do not believe the community will agree on an universal metric for general-purpose AI, and different metrics will arise.

Overall, I think it is positive that the EU is trying to regulate the use of AI. Unfortunately, I think it is a lost battle, as the technology is very new and evolves at a very high pace (something that beaurocracy might slow down). I defend that the EU should invest more on the evaluation and monitoring of AI, maybe more than on its development. After all, we cannot compete with the likes of NVIDIA, OpenAI/Microsoft, Google, Apple or Amazon, since they aquire all the relevant hardware before Europe does. Not even Intel or TSMC investing in Europe will allow us to beat US companies (or adjacent universities) in AI research. However, we can beat them in studying the societal impact of AI.