Stable Horde

The Stable Horde: AI image generation for everyone through mutual aid

After completing the KoboldAI Horde, and onboarding into the KoboldAI client, I felt that there is a really big opening for doing a similar thing using the open sourced AI image generating model, Stable Diffusion. I already have the code for setting up a crowdsourcing cluster, so it shouldn’t take too much refactoring to make the same underlying code work with Stable Diffusion.

The first thing I had to do was figure out what is going to run on the workers. For this, I decided to reuse the stable-diffusion-webui fork by simply adding my bridge code on top of it (as it doesn’t provide a REST API like KoboldAI). Once I had a valid bridge, it was time to fork the Horde.

And thus, the Stable Horde was born!

It follows the same approach, where workers running some version of Stable Diffusion constantly poll for new generations to complete and then send it back to the horde to hand it over to their final destination. For now the stable horde is only handling fairly basic text2image generations, but since it’s based on the webui, I can tap into the features that added upstrean much easier, without having to develop them myself.

The code started as a fork of the Stable Horde, but has by now become my primary repo. In fact, with the addition of the second version of the REST API, I have decided to merge both Hordes into a single repository in order to better share code updates (because copying code from one repo to the other was driving me nuts!). This is coming soon, and it means that the Stable horde will always remain in parity with the KoboldAI horde from now on.

While there are other free image generation tools out there, I believe none is doing anything like what I am attempting. Most of these are based on providing free Stable Diffusion by eating the costs themselves, but with an undefined business plan. And when I see that, my suspicions are already raised, as a free service like that, typically means you’re the product! It also doesn’t help at all that they are not sharing the code behind them.

Now you might say, “But db0, your service is also free, how come the same criticism doesn’t apply to you?”. Which is a great question. The answer is that the reason the Stable Horde is free is because it’s volunteer based. That means, at the end of the day, someone is indeed paying for electricity (that is, myself primarily atm), but the point is that it is self-managing through people’s innate drive for mutual-aid.

That means that if I get a jump in popularity, which in turn exceeds the Horde’s current image generation capacity (and therefore slowing things down too much), the belief is that there will be enough people annoyed by the speed, that they will join their own power to the horde to benefit themselves with higher priority, but also everyone else.

And yes, there is always some amount of “small print”. While the Stable Horde is built on anarchistic principles of mutual aid and direct action, the fact is that we do not control the underlying workers. Therefore it is theoretically possible for people to act maliciously on the worker side, which is why I always warn people who will use the Horde that I cannot guarantee that nobody will see your prompts. So act accordingly.

Nevertheless, one of the things I’m offering is something that I just haven’t seen anyone else do for image gen, and that is a fully functioning RESTful API. The purpose of this it to further enable image generation for everyone in new and exciting ways that enable tools to use this capability without bankrupting their owners for a side hobby whose demand suddenly spiked. Already people have started creating some interesting tools, such as a weather app which uses the Stable Horde to generate a dynamic image representing the weather, based on environmental conditions.

On my end, I am interested in helping game developers figure out ways to implement AI into their games. For this purpose I have already released a Godot Add-On which allows you to request AI image generation during a game’s runtime. I have further used this add-on to create my own Stable Diffusion GUI client that can run on any device, without the need for a complicated install procedure, or a GPU.

All of this is just scratching the potential of what can be achieved by allowing automation to connect directly to Stable Diffusion (or text generation), and I’m excited to see what people will come up with in the future!

The Kudos-based economy for the KoboldAI Horde

Work continues on the KoboldAI Horde apace, and in the past week I’ve added oauth auhentication but kept the anonymous access live as well. Let me tell you, figuring out how to use the flask.dance module for discord was a complete PITA.

But I got it done, and even added github authentication (and hopefully google soon, if they stop asking for silly things)

The authentication was added to allow me to build the next step, which is to be able to balance usage from the community.

The thing I expect to happen is that as the service becomes more popular, we might have way more clients trying to use the horde than we have actual contributing servers, and therefore we would run into performance bottlenecks. This could become unworkable especially if things like bots start using this service anonymously etc.

To provide some automatic balance, I have now introduced the concept of Kudos into the mix. A Kudos is a reward gained when someone contributes to the well-being horde in some way. There are two built-in methods to gain Kudos at the moment:

  1. Any time your KoboldAI server generates text for someone, you receive tokens based on the amount of text generated and the power of your model.
  2. KoboldAI servers get “uptime” rewards every 10 minutes they stay online and check-in looking for more requests. This incentivizes people leaving their instance running even in non-busy times.

On the flip-side, people using the Horde as clients are likewise consuming Kudos to do so. Every prompt you send, will reduce your balance by the same amount of Kudos rewarded to the server which fulfilled your request. Effectively you’re “thanking” the people running the instance which helped you.

But unlike typical currencies, you can still use this service even if you don’t have any Kudos. You simply go negative, which represents your “debt” to the community. This allows people to use the Horde anonymously as well (through the common Anonymous account) which simply keeps going more and more in negative Kudos.

But to avoid abusing this service by people who want to take and give nothing back, I needed to find a way to disincentivize negative kudos balances. And I just implemented the solution to do that which is a fairly simple one.

You kudos balance corresponds to your priority in the queue of requests

This means that if there’s plenty of servers around and not a lot of requests, nothing much changes, even for anonymous clients and they get to enjoy the full speed of the horde.

However on times of congestion, the requests sorted by kudos-order. The people with the most kudos get to have their requests fulfilled first, while those with the least, such as the Anonymous account, will get their generated last.

With some other tools provided such as bridge-based priorities, and server-owner-preference, this should allow owners of servers to make sure that not only “good” actors are the first to use their resources, but also to find their own ways to provide a service to selected members of the community. For example someone might set their family members to have priority on their server gens, even if those members are deep in negative kudos.

Along with that, I’ve deployed a kudos transfer service where peers can send kudos directly to others. So someone who has accumulated a large amount, might use that to reward good behavior in the community, such as writing documentation, or helping others. The kudos transfer can also happen via REST API, which can allow even automated tools to participate, such as discord bots which might trigger on special smileys assigned to posts and give a small kudos reward to the recipient.

There are of course many other things to consider, such as actions by malicious actors who might try to game the system. I really hope I won’t have to deploy countermeasures for people abusing community goodwill.

But until then, I really enjoy seeing the excitement from the KAI community, especially as heavy models like the fresh Erebus 13B are deployed into the horde. With the kudos infrastructure in place, there is now potential for new dynamics and reward systems to emerge organically from the community which will serve as an excellent guide on how to best proceed with this project.

A Horde of KoboldAIs

The KoboldAI Horde: AI writing for everyone through mutual aid

Those who’ve followed my progress in developing Hypnagonia would know by now that I’ve been working on the integration of KoboldAI with Godot for the automatic generation of stories. This solution while working never quite satisfied me, as it required quite a lot of investment on behalf of a player who wanted to generate stories.

That approach left me unsatisfied. As it happened I had an idea to use the new KoboldAI API to create a distributed cluster based on consumer GPUs in people’s PCs. The concept being that one would connect their PC in some fashion to a server software and whenever someone sent a request for generation, an available PC would pick it up, generate it, and send it back to the requester.

The requester themselves would therefore not need a powerful GPU (or skill to use Google Colab) to use KoboldAI, while people who’s PC is otherwise sitting idle, would be supporting the other members of the community.

So after some discussions with members of the community, I decided this idea had legs and I wanted to build it before I continued with Hypnagonia. I’ve been working non-stop on this for the past week and I now feel it’s at a pretty good state.

Introducing the KoboldAI Horde!

This is a python server which you run on a server somewhere and it provides an interface with which people can request GPT writing generations. The second part is the bridge, which is what people who have their own KAI instances run, in order to connect the KAI server to the server. The last piece of software of course is the KoboldAI client which runs the models generating the text.

Until now, the only option for people without such powerful hardware would typically to use a service like NoveAI or AI Dungeon, where one has to pay for the service. They also provided a fancy interface and tools to help people write their individual stories. Aside from the cost however, there were also limitations. Dungeon AI recently imploded due to their own actions, and a lot of people were left without a home.

And of course, for a free software video game, such services are prohibitive, as I can’t pay out of pocket for the text generations of dozens of players (or imagine if my game ever became actually popular).

After a bit of hacking of the KoboldAI client itself, I also added functionality to allow someone to use their own KoboldAI client to talk to the Horde directly. Which means someone with a potato PC, can still use KoboldAI directly.

Now there are some obvious limitations as you might expect. First of all, the availability of the models in the horde is dependent on who is supporting it at the moment. If only people with weak GPU are in, the best you’ll find is a Nerys 2.7B. If however some of the big chonkers are in, you might be able to use KoboldAI as if you have a 20B model behind it.

The other problem is of course questions of privacy. Even though the text is encrypted during transfer, and even though the horde does not store any prompts or generations, at the end destination, the owner of the server can see all your prompts if they so wish, even if they don’t know who you are. So for those wanting the really steamy stuff, or perhaps those who write stories using real people and locations, this might be a deal breaker.

However for more normal stories, or for more generic generations such as for utilities and apps, this is hardly a concern.

Finally we’re still new, so currently everyone is playing nice. But there’s always the potential of bad actors, who might food the horde with garbage generations just to shut it down. There’s nothing I can do about someone dedicated to do that except go into a whitelist mode, and have the horde become an invite-only service, much like a private bittorrent tracker. In fact, anyone could set up their own private instance for their own community, for those situations where they want only trusted people to use it.

Eventually my plan is to follow the bittorrent approach for usage and contributions as well, where people will only be able to use the horde if they contribute somehow to the KAI community. Whether by adding their own GPU to the horde, or by writing documentation, etc.

But ultimately I want this to be a mutual aid based service. Where those who have the capacity help those who do not, and the latter find some other ways to make it up, for the uplifting of everyone in the KoboldAI community.

And before anyone suggests to tie this to some web3 token: Fuck that shit! I will work integrate with any cryptocurrencies! That is poison for our communities AND for our ecosystem.

The owner of the KAI client repo was also kind enough to redirect their domain to my KAI Horde instance, so now we have a very fancy url as well.

Official KoboldAI Horde

Already this is working amazingly well and I’m working on improvements daily. I’m excited to see what kind of doors this will open.

My first steam game

Hypnagonia now has an official steam page!

It’s not much but it’s mine 😀 It took me a while to gather everything needed to create the steam page as Steam is way way more thorough than Itch.io. The benefits over itch of course are the automatic updates you’ll be able to receive. And for me, hopefully being on steam might attract a few more eyeball than might become collaborators 🙂

Why my ADHD means I end up making an ugly video game.

Hypnagonia has copied a lot of design paradigms from Slay the Spire, primarily because I needed a baseline to start working on content, instead of getting stuck in trying to figure out all the details of the design for every aspect. But you may be wondering why almost a year since I started it, it still looks like something to manage servers. To explain that, I need to give some background.

How “battles” look in the latest version

As someone with ADHD, it’s very easy for me to be overwhelmed by the frontloaded effort needed to be able to start something as large as developing a new game, and give up. Copying the design of something else is way more conductive to jump straight into doing something I already know how to do well (in this case, coding and card game design).

I am very lucky that my “autistic comfort zone” so-to-speak is programming (and general PC use), so that counteracts my executive dysfunction to a degree that allows me to start working on something, just for the joy of having a goal to program something. I kinda think of this “autistic drive” as a car battery ignition. It allows me to kickstart myself to do something which is one of the massive blocking points of ADHD.

However it’s not a trick that can always work, and it needs the right circumstances.

I got first interested in programming when I was 10 years old. I even pestered my mother enough to voluntarily go to 2 years of programming school back then – and sit through some of the worst lessons in programming one can have. Who the hell tries to teach 10-year olds Fortran by reading from the manual? Later on, I didn’t manage to get into university – due to just wanting to play computer games instead of studying for the exams. Instead, I went to a vocational school for programming for 2 more years.

When did I finally start programming for myself? When I was in my 30s. I literally learned programming and then didn’t do anything with it until I had the right circumstances. I tried multiple times to motivate myself to actually do something I knew I liked doing, but I couldn’t because I didn’t know what to do with it that was achievable for my skills. Things like making video games were out of the question as I had nowhere the skill needed to even begin. Yes, I know everyone starts like that, but try telling that to my stupid ADHD brain who does not get the concept of not getting the happiness chemical immediately.

What I truly needed was something I could start with very little programming needed and then built up my skills little by little, but having a clear but achievable improvement I could do.

In my case, my circumstances ended up being my interest in coding old card games in OCTGN, which requires very little code to start, but allows you to go bonkers with python if you want to (even if it doesn’t make it easy). The way it worked for me, is that I kept wanting to add more features, but each feature was just simple enough that I could see myself achieving it within a day or so. It kept me motivated enough to keep going.

All that worked pretty well until my eventual burnout after 7 years or so due to juggling too many projects at once.

The good news was that I had already picked up enough gamedev knowledge to give me some confidence. Once some of my burnout started to wear off 3 years later, I wanted to get back into card game design, but I didn’t want to touch OCTGN anymore. And then I discovered the Godot Engine (the way how is a post for another day) and after a few false starts, I got the idea to start on the Card Game Framework.

The reason why work on CGF is what worked, is because I had just enough knowledge of the things I needed to build (due to my experience with OCTGN), so that my autistic kickstart gave me enough momentum to overcome my ADHD executive dysfunction and head straight to Hyperfocus.

So, back to Hypnagonia, when I initially got the first concept for it, I knew it was way bigger than what I had done until now. Especially since I have no support network (I am not in a modding scene, and none of my contacts from my OCTGN, Android: Netrunner or Doomtown days seemed interested). So I knew I had to settle in the solodev role.

I also knew that if I tried to “reinvent the wheel” too much with my game, I will never get going as I will be stuck trying to think of how everything should work together until I give up due to complexity.

So early on, I decided to mostly copy Slay the Spire, as the granddaddy of the genre, while adding the few spins I wanted to use, which I knew were manageable for me. This means I settled to clone the UI look and core gameplay loop at least. The reason is, by now, I know how to program a GUI I can see in my head, and I know how to design card games, but I have no idea how to design good looking graphical interfaces, fancy animations, shader and effects or even any sort of art.

By using the StS layout, I could bypass my annoying brain trying to trick me out of doing something cool, by not having it get existential dread about trying to do something it doesn’t yet know how to do!

The main reason then why Hypnagonia still looks like so bad, is because I have no idea how to fix it, and any time I consider that I should do it, my brain goes: “Nope, you don’t know how to do it! Procrastinate a little instead. Reddit is just a button away!”

If I were to nevertheless stubbornly pressure myself to not do anything else except trying to improve the look of the game, I would procrastinate so much, I risk loosing my motivation for developing Hypnagonia completely. I had more than one close call with this.

For example, early on, I decided not to copy StS overworld mechanic (a map with encounters) because I wanted a more storyline-based experience. However I had no idea whatsoever what to replace it with. I got so demotivated that I couldn’t think what to do about it, I started distracting myself with other things. I was stuck and losing interest worryingly fast.

Fortunately, an experienced board game designer friend of mine agreed to brainstorm a little with me, and managed to throw an idea out that broke my “designer’s block” which eventually became the dream journal I have now.

So experience has taught me to know my limits. And at the current point, my limits are game UI/UX. Staying within the StS guidelines allows me to have a usable game. My plan is to make something playable end-to-end, even if not it’s not good looking and is full of placeholders. To salvage the rest, I just hope that I can attract specialist in the areas I cannot handle.

Every day I think about working on Hypnagonia, I need to kickstart my motivation and push through my urge to procrastinate “a bit” first. The way to do this, is to stay within my comfort zone, which is programming and game design.

So in the end, my autism helps me overcome my ADHD, but it has its limits. Therefore, the game look suffers.

Hypnagonia in the news!

GamingOnLinux recently wrote a small article about Hypnagonia! This served to drive an order of magnitude more people to the game than before. This was driven by a new member of the community who discovered Hypnagonia through matrix.

This in turn made hundreds of people discover the game, and we already had multiple people hitting me for collaboration. We even got a new piece of art and it’s really good!

We also have other members of the community helping me generate Artbreeder journal art, which some really disturbing results. They are also frequently suggesting random ideas which I take twist them into horrible Torments 😀

These ideas have driven the creation of the new new Torments. One of which I wrote about here and the other I’ll et you experience yourselves.

I’m really happy that the community is picking up. The General discussion channel is now fairly busy with interesting discussions, (and bug reports 🙂 ) banter, and frequent mentions of cockroaches for some reason.

I also have tripled the amount of people following the game on itch.io which is great.

I made an itch.io page

I always knew I had to do CI/CD for my development, but I just hadn’t given any priority yet. As such, until now I was still manually exporting Hypnagonia when I had a stable release, then manually uploading the html to my own site through scp, ssh to the site, and copy the files to the web directory. All so that I can link people to a bland page so that they can play the game online.

And for more feature-packed releases, I would also export the versions for Linux, Windows and mac, create a new github release and upload them there.

It was an unnecessary manual procedure and it always bothered me. But I had other priorities on my end and I kept pushing back the improvement on that end.

That is, until yesterday, where I run into this video introducing DevOps practices to game development:

And that kinda shamed me into going through with it.

Unfortunately interacting with my own webhost was always hacky and felt amateurish. So I decided to onboard Hypnagonia to itch.io. This provides me some benefits. As part of the community there, I can start getting more organic discovery. It provides some interesting metrics and very imprtantly, it’s an estabilished platform which means there’s plenty of guides and products to integrate it easily into my Continuous Delivery pipeline.

Unfortunately, I realized that embedding the game into itch.io doesn’t play well with my current viewport size and the “static” way I had designed it. And that was a rabbit hole…

First I adjusted my main menu screens to adjust automatically according to the viewport size. That worked OK-ish for not ridiculously-small resolutions. It’s fine, we can look at that later

But then I discovered that even small reductions in the viewport, make the cards look massive, as they are never scaled. So I needed to shrink cards according to the viewport size somehow…

Long-story short: I spent around 6 hours yesterday just giving the Godot Card Game Framework functionality to handle smaller resolutions somewhat gracefully. It’s not perferct, but it’s good enough to allow itch.io embed.

And since I was at it, I made some quality of life improvements. And wrote about them into an itch.io devlog.

I’m going to be writing some devlogs there now and then. Not sure how I will handle the integration with this blog. Maybe just post a link to them here when I write them? What do you think?