Tales from the jar side: Flux 1.1 images using Kotlin, The io TLD, AI vs Lamar/Drake, and the usual silly tweets an toots
I followed the sine to trigonometry island cos I wanted a tan. (mathematical rimshot)
Welcome, fellow jarheads, to Tales from the jar side, the Kousen IT newsletter, for the week of October 6 - 13, 2024. This week I taught my Managing Your Manager course on the O’Reilly Learning Platform and my regular courses at Trinity College.
Flux 1.1 [pro] Using Kotlin
Last week I talked about the new image generator called Flux 1.1 [pro] from Black Forest Labs, and how it provided a REST-based web service I could access using Java. This week I spent a bit more time working on a Kotlin implementation instead. The reason I chose Kotlin is because the API for the image generator is asynchronous, and Kotlin has capabilities built-in to handle that.
What does that mean? When you access the API, you need to follow a three-step process:
Send an initial request with the prompt, the size, and other properties. That returns an id right away and starts generating the image.
Poll a different endpoint using that id as part of a query string, waiting for the status to change from Pending to Ready. When the image is ready, a property is returned with the URL to the generated image.
Download and save the image.
In their examples, they set up a loop that runs forever (what is called a “while true” loop) that repeats every half a second, and breaks out of it when the image is ready. That’s a technique sometimes called “busy waiting” and can be risky if the loop doesn’t terminate.
When I did the Java implementation, I briefly tried rewriting that part of the program using something called a ScheduleExecutorService
, but while I got a version of it running properly, it still wasn’t quite right. With Kotlin, however, the language has a capability called coroutines, which are lightweight threads that execute without blocking the main thread.
(As of version 21, Java now has virtual threads, but there’s no cancellation mechanism to terminate multiple ones. That will be part of a specification known as Structured Concurrency, but that’s not out yet.)
I’m teaching my Software Design course at Trinity College using Kotlin, so I needed an excuse to dig into Kotlin again. That meant I needed:
A way to convert Kotlin classes to JSON data, a process known as serialization.
A way to pass HTTP requests to the service and process the responses.
A way to handle the polling loop using coroutines.
Fortunately, Kotlin has facilities for all of those. The serialization is done with an additional package called, naturally enough, kotlinx-serialization. See the Kotlin Serialization Guide for details.
For the networking, I chose a library that’s not part of the standard distribution but comes from the same source, JetBrains. It’s called Ktor, which uses coroutines under the hood for all their networking. I used their Ktor Client to access the image service and handle all the details off the main thread.
The fun part was using Kotlin Flows to implement the polling loop. I’d never done that before, and it turned out to be really easy. Apparently, that’s a natural use case for flows, and it worked exactly as designed.
That’s already probably more than you wanted to know, so I’ll just say that the code itself is in this GitHub repository and leave you to it.
One side note. When I started writing the code, the Ktor library was on version 2.3.12 or something similar. A day later it changed to 3.0.0. I was worried I would need to update everything, but as it turned out, I didn’t need to change any code. Everything worked exactly the same way. Presumably if I had a Ktor server implementation that would have been different, but the client stayed the same, at least the parts I used. Whew.
A vanishing country, and with it, a TLD
There’s a big story making its way through Internet circles. From this article at an online publication called Every:
On October 3, the British government announced that it was giving up sovereignty over a small tropical atoll in the Indian Ocean known as the Chagos Islands. The islands would be handed over to the neighboring island country of Mauritius, about 1,100 miles off the southeastern coast of Africa.
The story did not make the tech press, but perhaps it should have. The decision to transfer the islands to their new owner will result in the loss of one of the tech and gaming industry’s preferred top-level domains: .io.
The Chagos Islands was formally known as the British Indian Ocean Territory, thus giving it the top-level domain (TLD) called “io”. That’s a big deal, because I/O also stands for input/output and is one of the more popular alternative domains for web sites around the world. For example, GitHub uses github.io for many of its documentation sites.
Renting TLDs can be quite lucrative for some countries. An example is “ai”, which is owned by the tiny island in the Carribbean called Anguilla. Their government made 30% (!) of it’s overall budget last year from companies that wanted to license an Internet address that ended in ai. Even the Black Forest Labs image generator from the previous section (from a company hosted in Germany) links its documentation to https://doc.bfl.ml, where presumably ml is intended to represent machine learning, as opposed to Mali, the country that actually owns that TLD.
(The Ollama web site, used to run LLMs on your local machine, used to be at ollama.ai, but now is at ollama.com. I presume they didn’t want to pay the registration fees.)
The article discusses the chaos that engulfed the Internet when (1) the breakup of the Soviet Union removed the “su” TLD and replaced with “ru” for Russia, and (2) the years after Yugoslavia fractured into multiple countries and the resulting chaos as all of them fought over the “yu” TLD. After that, IANA, the international body that manages all this, created hard and fast rules that say when a country goes away, so does its TLD. Period.
That, however, is going to create a lot of problems this time. Fortunately, there’s a five-year waiting period (and an available five-year extension), so all those giant sites with lots of money have time to either come to an agreement or fight it out, depending on how it all goes. From a spectator sport point of view at least, it ought to be entertaining.
AI v Kendrick Lamar v Drake
I’m teaching a course at Trinity College (Hartford) called AI Integration, and we were discussing the limitations of AI chat tools. One point that came up was how they only know what was in their training data, which always has some cut-off date.
I asked the students for a question I could pose whose answer would be different recently than originally, and someone asked about the feud between Kendrick Lamar and Drake. As you probably know (but may not if you’re near my generation), the two of them have had a rivalry going back a decade, but which exploded this year.
I asked GPT-4o about it, using LangChain4j:
String response = chatModel.generate(
UserMessage.from(
TextContent.from("""
What was the beef about between
Drake and Kendrick Lamar?
""")))
.content().text();
System.out.println(response);
Here was the initial response:
The tension between Drake and Kendrick Lamar can be traced back to a series of competitive exchanges and perceived jabs in their music, interviews, and public appearances over the years. Here are some key moments that contributed to their rivalry:
1. **"Control" Verse (2013)**: Kendrick Lamar's verse on Big Sean's track "Control" is often cited as the spark that ignited the rivalry. In the verse, Kendrick called out several rappers, including Drake, challenging them and asserting his dominance in the rap game. This bold move was seen as a direct challenge to his contemporaries.
2. **Response Tracks and Subtle Disses**: Following "Control," both artists have included subliminal shots at each other in their music. For instance, Drake's track "The Language" and Kendrick's "The Heart Part 4" contained lines that fans interpreted as aimed at one another.
3. **Interviews and Public Comments**: Both artists have made comments in interviews that many interpreted as digs at each other. For example, Kendrick has criticized the commercialization of rap, which some fans speculated was directed at Drake, who has a more mainstream appeal.
4. **Album Releases and Competition**: As both artists released new albums, the competition for chart dominance and critical acclaim further fueled the rivalry. The timing of their releases and the themes within their albums often led to comparisons and discussions about who was the better artist.
5. **Overall Styles and Personas**: The differences in their artistic styles and personas also contribute to the rivalry. Drake is known for his emotional and melodic approach, while Kendrick is celebrated for his intricate lyricism and social commentary. This contrast has led to debates among fans about who represents hip-hop better.
While there have been moments of camaraderie and mutual respect between the two, the competitive nature of the hip-hop industry, combined with their contrasting styles, has kept the rivalry alive. As of my last update, the situation remains dynamic, with both artists continuing to evolve in their careers.
As you might expect, there’s nothing in there about the feud going nuclear during 2024.
One way to handle that problem is to supply more up-to-date information as part of the prompt. This is sometimes called prompt stuffing, and works well if the additional info fits inside the AI’s context window, defined as the maximum number of tokens that can be included in the request.
Since I was already using LangChain4j, I knew I had a document loader available that could download information from a URL. I therefore modified the code to use this:
Document feudDoc = UrlDocumentLoader.load(
"https://en.wikipedia.org/wiki/Drake%E2%80%93Kendrick_Lamar_feud",
new TextDocumentParser());
if (feudDoc.text().length() > 128 * 1024) {
System.out.println("Document too large: " +
feudDoc.text().length());
System.out.println(feudDoc.text().substring(0, 1000));
return;
}
String response = chatModel.generate(
UserMessage.from(
TextContent.from("""
Given the information in %s,
What was the beef about between
Drake and Kendrick Lamar?
""").formatted(feudDoc.text()))
.content().text();
System.out.println(response);
In other words, go download the current Wikipedia article on the feud (because of course there is one) and add it to the query. The problem, as you can probably guess from the included “if” statement, is that the Wikipedia page turns out to be way too long to fit inside the context window. In fact, the page itself contained over 487K characters. Whew! Google’s Gemini 1.5 could handle that, but that’s a lot no matter what you use.
Why so large? In addition to all the text, the document is full of HTML tags, CSS styles, and lots of JavaScript, not to mention the 178 (!) references at the bottom. It’s a pretty bloated page, even as Wikipedia pages go.
It finally occurred to me that I had a work-around. Instead of using the document loader (which is really the first step in a RAG application, and we haven’t discussed that yet), I could use the jsoup library directly. The jsoup library is for parsing HTML web pages using Java, and it’s included as a dependency in LangChain4j already.
I therefore went with this:
String wikiText = Jsoup.connect(
"https://en.wikipedia.org/wiki/Drake%E2%80%93Kendrick_Lamar_feud")
.get()
.text();
System.out.println("Length of wikipedia article " +
wikiText.length());
It turns out the raw text (which is what that text()
method extracts) is only about 78K. That’s still a lot, but fits inside the 128K context window for GPT-4o. I added the article to the query and ran it. Since I imagine you’re wondering by now, here’s the resulting answer:
The feud between Drake and Kendrick Lamar, which has evolved over the years, centers around competition in the hip-hop industry, subliminal disses, and personal accusations. Here's a breakdown of the key elements of their beef:
### Background
1. **Initial Collaboration**: Drake and Kendrick Lamar initially collaborated on tracks like "Buried Alive Interlude" (2011) and "Poetic Justice" (2012), and they seemed to have a cordial relationship.
2. **"Control" Verse (2013)**: The feud began to escalate when Kendrick dissed several rappers, including Drake, in his verse on Big Sean's track "Control." This was perceived as a challenge to their status in hip-hop.
### Escalation of Disses
3. **Subliminal Shots**: Over the years, both artists exchanged subliminal shots in their songs. For example, many interpreted Drake's "The Language" and Kendrick's BET cypher in 2013 as indirect disses toward each other.
4. **Ghostwriting Accusations**: Kendrick's "King Kunta" (2015) was seen as a jab at Drake, especially amid allegations of Drake using ghostwriters.
5. **Continued Tension**: The rivalry simmered with occasional hints of diss tracks and comments, such as Kendrick's "The Heart Part 4" (2017), which many believed targeted Drake.
### Recent Escalation (2023-2024)
6. **J. Cole's "First Person Shooter"**: In October 2023, J. Cole's song suggested that he, Drake, and Kendrick were the "big three" of modern rap, which Kendrick responded to unfavorably in March 2024 with "Like That," dissing both Cole and Drake.
7. **Back-and-Forth Disses**: Following Kendrick's "Like That," the feud intensified with Drake releasing "Push Ups" and "Taylor Made Freestyle" as responses. Kendrick retaliated with tracks like "Euphoria" and "Meet the Grahams," which contained serious allegations against Drake, including claims of domestic abuse and pedophilia.
8. **Public Reactions**: The feud garnered significant media attention, with various artists and celebrities weighing in. Many commentators have noted that Kendrick is often viewed as the victor in this ongoing rivalry, citing his lyrical prowess and the impactful nature of his diss tracks.
### Current State
As of October 2024, the feud is ongoing with both artists continuing to release diss tracks aimed at one another, and it has become a significant topic within hip-hop culture, reflecting broader themes of authenticity, competition, and personal grievances in the industry. The rivalry has sparked debates about the nature of rap beef in the digital age, with social media playing a crucial role in how these exchanges are perceived and amplified.
In class, that led to a spirited discussion of whether Drake really did or did not get owned, and whether or not Kendrick will perform Like That during the Super Bowl half-time show next January (the consensus is “definitely yes”).
All in all, I think that was a successful exercise for the class. :) As to the actual beef, I’m glad the students gave me credit for knowing it even existed (which I need to acknowledge my son for bringing to my attention before it went viral), though I must admit I have no idea about any of the music. I guess I’ll find out during next year’s Super Bowl.
Tweets and Toots
No library for you
That does seem rather cruel. Most universities are eager to give you an alumni email address these days, which makes it easier for them to track you and ask for money, but I don’t think library access is included.
Libraries
Speaking of libraries, there’s this:
Fine, but do it quietly.
Pop v Soda
That’s a variation on an old gag. One of the comments stated it pretty clearly:
Iggy Coke? I have no idea where the data for those figures comes from, even assuming it exists. If you have an opinion, feel free to add it in the comments.
Maternity humor
Pretty good gag to start them off early.
Cats in a haunted house
Credit Mark Parisi, offthemark.com.
Rock-Paper-Scissors for cats
I don’t think that rock is going to beat those scissors. Just saying.
Musk again
My sense is that everybody is going back to calling it Twitter, regardless of what Musk wants, probably because that annoys him. His appearance at that Trump rally in Pennsylvania made people wonder what drugs he’s actually on. Then he had the big announcement about his robotaxi service, and the industry responded by dropping Tesla stock by 8% because nobody believes he’ll be able to deliver. Even worse, the “robots” he had serving drinks were being manipulated by hidden employees, and of course he lied about it.
Not a good week for a guy who is constantly hurting himself.
Nobel prizes
Demis Hassabis was a chess prodigy who decided to go into AI and was one of the founders of Deep Mind, now owned by Google. They created AlphaZero, which had a huge impact on the chess world, AlphaGo, which beat the reigning Go world champion, and AlphaFold, which unwrapped the structure of proteins and is presumably what the Chemistry prize is all about.
AI guys winning the Physics prize was controversial, to say the least.
I’m sure the current AI bubble will burst, but apparently not yet.
Lasagna v spaghetti
In the object-oriented world, we don’t write spaghetti code. We write lasagna code, which is what you get when you add too many layers.
Last by not least, a Batman joke:
Sorry, Commissioner
The new Penguin series on HBO (or Max, or whatever they’re calling it these days) is fantastic. There’s a new episode tonight. I’m glad they’re only once a week, though, because each one stays with me for a few days afterwards.
Have a great week, everybody!
Last week:
Managing Your Manager, on the O’Reilly Learning Platform
My regular Trinity College schedule
This week:
Reactive Spring, on the O’Reilly Learning Platform
My regular Trinity College schedule. The inimitable Venkat Subramaniam will be in town and has agreed to handle two of my three classes on Thursday. That ought to be fun. :)