HackerTrans
TopNewTrendsCommentsPastAskShowJobs

JoshCole

no profile record

comments

JoshCole
·2 months ago·discuss
That is part of why https://mieza.ai/ is giving a grounding layer that is backed by game theory. Actions have consequences. Tracking decisions and their consequences is important.

One thing that becomes very clear from this sort of work is just how bad LLMs are. It can be invisible when you're working with them day to day, because you tend to steer them to where they are helpful. Part of game theory though is being robust. That means finding where things are bad, too, not just exploring happy paths.

To get across just how bad the failure cases of LLMs are relative to humans, I'll give the example of tic tac toe. Toddlers can play this game perfectly. LLMs though, don't merely do worse than toddlers. It is worse then that. They can lose to opponents that move randomly.

They can be just as bad as you move to more complex games. For example, they're horrible at poker. Much worse than human. Yet when you read their output, on the surface layer, it looks as if they are thinking about poker reasonably. So much so, in fact, that I've seen research efforts that were very misguided: people trying to use LLMs to understand things about bluffing and deception, despite the fact that the LLMs didn't have a good underlying model of these dynamics.

It is hard to talk about, because there are a lot of people who were stupid in the past. I remember people saying that LLMs wouldn't be able to be used for search use-cases years back and it was such a cringe take then and still is that I find myself hesitant to talk about the flaws. Yet they are there. The frontier is quite jagged. Especially if you are expecting it to be smooth, expecting something like anything close to actual competence, those jagged edges can be cutting and painful.

Its also only partially solvable through scale. Some domains have a property where, as you understand it better, the options are eliminated and constrained such that you can better think about it. Game theory, in order to reduce exploitability, explores the whole space. It defies minimization of scope. That is a problem, since we can prove that for many game theoretic contexts, the number of atoms is eclipsed by the number of unique decisions. Even if we made the model the size of our universe there would still be problems it could, in theory, be bad at.

In short, there is a practical difference between intelligence and decision management, in much the same way there is a practical difference between making purchases and accounting. And the world in which decisions are treated as seriously as they could be so much so exceeds our faculties that most people cannot even being to comprehend the complexity.
JoshCole
·3 months ago·discuss
> Can you talk more about why you chose CLJ for datascience / ML.

I use Python for a lot of machine learning. My vision transformers, for example, are in Python. There is a lot to like about the Python ecosystem. Throwing away libraries like ablumentations and pytorch because you move to a different ecosystem is a real loss. You probably ought to be using Python if you're doing machine learning of the sort that one immediately thinks of when they see ML.

That said, data science and machine learning are words that cover a lot of ground.

Python often works because it serves as glue code to more optimized libraries. Sometimes, it is annoying to use it as glue code. For example, when you're working on computational game theory problems, the underlying data model tends to be a tree structure and the exploration algorithm explores that tree structure. There is a lot of branching. Vanilla python in such a case is horrifically slow.

I was looking at progress bars in tqdm reporting 10,000 years until the computation was done. I had already reached for numba and done some optimizations. Computational game theory is quite brutal. You're very often reminded that there are less atoms in the universe than objects of interest to correctly calculating what you want to calculate.

Most people use C, C++, and CUDA kernels for the sort of program I was writing. Some people have tried to do things in Python.

> Are there any benefits of using it over Python?

There is an open source implementation of a thing I built. It solves the same problem I solved, but in Python and worse than I solved it and with a lot of missing features. It has a comment in it, discussing that the universe will end before the code would finish, were it to be used at the non-trivial size. The code I wrote worked at the non-trivial size. Clojure, for me, finished. The universe hasn't ended yet. So I can't yet tell you how much faster my code was than the Python code I'm talking about.

> And how is the interop with Python libs?

Worked for me without issue, but I eventually got annoyed that I had to wait for two rounds of dependency resolution in some builds. Conda builds can sometimes have issues with dependency resolution taking an unreasonable amount of time. I was hitting that despite using very few libraries.
JoshCole
·3 months ago·discuss
I know others already pointed out a ton of things, but having worked with Clojure in 2016 and doing active Clojure development for my startup now I feel like I have to chime in too.

In 2016, Clojure was not great for serious data science. That has changed substantially and not just via Java Interop.

- It now has cross ecosystem GPU support via blueberry libraries like neanderthal, which in benchmarking, outperform some serious Java libraries in this space.

- It has columnar indexed JIT optimized data science libraries via cnuernber and techascent part of the Clojure ecosystem. In benchmarking they've outperformed libraries like numpy.

- The ecosystem around data science is also better. The projects aren't siloed like they used to be. The ecosystem is making things interoperate.

- You can now use Python from Clojure via the lib-pythonclj bindings. In general, CFFI is a lot better, not just for Python.

- The linters are way better than they used to be. The REPL support too.

Clojure already had one of the best efficiency scores in terms of code written to what is accomplished, but now you also get REPL integration, and LLMs have been increasingly capable of leveraging that. There are things like yogthos mycelium experiments to take advantage of that with RLLM calls. So its innovating in interesting new ways too, like cutting bugs in LLM generated code.

It just doesn't feel true to me that innovation isn't occurring. Clojure really has this import antigravity feel to it; things other languages would have to do a new release for, are just libraries that you can grab and try out (or maybe that's the python)
JoshCole
·4 months ago·discuss
I've been obsessed with game theory for years. Started by reimplementing papers, got annoyed at how bad the tooling was, wrote my own, and somewhere along the way realized the field's core assumptions about competition are wrong. Helps that many of my friends are from the competitive gaming scene -- multi-R1 players, MLG winners, etc. So I get to have a view on strategy from both the FANG MLE/SWE side but also the actually competing at the highest levels side.

Decided to found a company with some of those friends, bridging computational game theory and large language models :)

https://mieza.ai/
JoshCole
·7 months ago·discuss
It is pleasantly sensible since servant leadership in a sense creates an innocence because of the incents; the underlying reality is that wisdom dwells with prudence. Principles of revelation arise from incentive compatibility. Aiming at the apparent target is good hearted folly.
JoshCole
·10 months ago·discuss
Very cool work Jan!

Have you tried experimenting with ham-fisted? I've found the libraries in the techascent part of the Clojure ecosystem to be very good performance wise. Ditto for neanderthal.
JoshCole
·10 months ago·discuss
Lisps (like Clojure) treat code as data (lists), so you write: `(if x (y) (z))` instead of Python’s `y() if x else z()`. So the code is more concise, but does less to walk a novice through it.

This gains a huge advantage, which allows even more concision: all code is data, so its easy to transform the code.

In Clojure if you want to add support for unless, a thing like if, but evaluating the opposite way you could do this: `(defmacro unless [p a b] `(if (not ~p) ~a ~b))`. Obviously if you wanted to do the same thing in Python you would in practice do `z() if x else y()`. However, you would do it that way because Python isn't as powerful a language. To actually do the same thing in Python you would need to...

1. Add __future__ support.

2. Update the Python language grammar.

3. Add a new AST type.

4. Add a new pass stage to the compiler.

5. Add a python library to integrate with this so you could use it.

Then you could do something like:

    from __future__ import macros

    defmacro unless(pred, then: block, else_: block = []):
        return q[
            if not u(pred):
                u*(then)
            else:
                u*(else_)
        ]

So in the trivial case its just hundreds of lines harder plus requires massive coordination with other people to accomplish the same feat.

This sort of, wow, it takes hundreds or thousands of lines more to accomplish the same thing outside of Lisp as it does to accomplish it within Lisp shows up quite often; consider something like chaining. People write entire libraries to handle function chaining nicely. `a.b().c().d().map(f).map(g)`. Very pretty. Hundreds of lines to enable it, maybe thousands, because it does not come by default in the language.

But in Lisp? In Clojure? Just change the languages usual rules, threading operator and now chaining is omnipresent: `(->> a b c d e (map f) (map g))`. Same code, no need to write wrapper libraries to enable it.
JoshCole
·4 years ago·discuss
> it's selfish to keep beautiful discoveries a secret.

I found a beautiful thing recently and planned to do a write-up on it eventually, but I know I might get distracted. So I'll share the beauty here since I don't want to be selfish!

In K means clustering you know you've stabilized if centers t = centers (t-1). Stabilization has occurred because no clusters were reassigned during the lloyd iteration. People already know this. In many implementations of k means clustering you'll find this check in the body of the loop as a special case which means the loop should end. You can't have this as the condition of the while loop because you don't yet have a centers t-1 on your first loop. Actually you can by supposing a hypothetical all nil cluster definition prior to initialization, but people don't tend to do that. That failure to do that is ugly in the same way that Linus refers to code which uses special casing as being ugly. It doesn't apply the same procedure to every iteration. They should do that and it would make the code more beautiful. However, that is not my discovery, but just a preference for beauty and consistency.

What I noticed is that the equality check is actually giving you a bitset that tells you whether any of the centers was changed. This is a more general idea than just telling you that you can stop because you are done. It is telling you /why/ you aren't done. It is also deeply informative about the problem you are solving in a way that helps the computation to be done more efficiently. I want to show it being deeply informative. So I'll touch on that briefly and then we can revisit the simplicity.

Clusters being reassigned tells you the general location that have the potential to need future reassignment. For example, in the range of 1 to a 1,000,000 on a 1d line if a cluster at 10 moves, but there is a cluster at 500, then you know you don't need to look at reassignment for any cluster above 500. I mean this in two sense. One is that nothing in clusters past the 500 can change. So you don't need to look at them. The other is that clusters past the 500 cluster can't even be nearer. So you don't have to find the pairwise distance to them. In the assignment stage of the lloyd iteration you don't even need to look at everything above 500. So you not only reduce the amount you need to look at in the N dataset items. You also reduce the number of k clusters centers you need to compare them to. In the 1 to 1,000,000 domain example for stuff below 500 that is probably going to be more than 99% of your data that you can skip and the vast majority of clusters that you don't even to need to check distance for.

Returning to the simplicity discussion it means you can write the loop without the special casing. Instead of a break when stabilization has occurred you have a selection criteria function which tells you the selection criteria for that step of the lloyd iteration. Obviously at the initialization stage we went from no definitions to k definitions. So the selection criteria function is well defined even for the very first iteration on an intuitive level.

Why do I find this beautiful? Well, we can not only eliminate the special casing, which is beautiful on its own, but we can rephrase each iteration in terms of a selection criteria generated by that equality check! We are never special casing; the reason we stopped was always because the selection criteria was the empty set. We just didn't think of it that way, because we didn't phrase the update step in terms of the generation of a selection criteria for updates.

And when you do, suddenly it becomes obvious how to do certain parallelizations because your selection strategy tells you where to kick off another refinement iteration. And /locality/ in a dimensional space is determining where the updates get passed. I have this strange feeling that if we just keep pulling on this idea that we'll be able to eliminate the need for loops that await all cluster updates and instead express the computation in a massively parallel way that ends up taking advantage of the topological structure of the problem: I mean, clearly if you have two clusters that moved one at 5 and another at at 900900 you don't /need/ to wait for 5 to finish its refinement to know that it /isn't/ going to impact the next step for refinement at 900900, because there are so many clusters between them. So you should be able to proceed as if 5 cluster movement has no impact on 900900 cluster movement. Only if they drift closer and the topology differs do you have to backtrack, but since we already need to pass these updates through the topological structure we have a fairly straightforward way of declaring when it is appropriate to backtrack. This phrasing is really stupid for the toy problems that people solve in classrooms and when trying to understand things because of the overhead of keeping track of the work and the wasted work, but I have a feeling that it might be practical. In real massive problems you already have to pay the cost of keeping the work because stuff fails and you need to retry and in particular the geometric probability distrubition of failure is high enough that we just have to assume that stuff fails in these massive cases. So the added cost of keeping the work around during the computation isn't as extreme a barrier. It's basically optimistic massively parallelized clustering, but with a resolution protocol for how to handle two optimistic clustering runs which collide with each other, because the natural problem of scale forces redundancy on us effectively making the choice to be redundant free rather than expensive wasted work.

Maybe nothing will come of these thoughts, but I found the first thought pretty and it provoked the second line of reasoning, which I found interesting. I'm working on a k-means clustering system that incorporates the good ideas from several k means research papers and I plan to explore these ideas in my implementation, but in the spirit of not hiding beautiful things, I hope you enjoy.

Also, as an aside, these aren't completely new ideas. People have noticed that you can use the triangle inequality to speed up computation for a while and shown it to speed up computations. It's more of an observation of the way the looping structure can be seen in a non-special cased way, how that suggests ways to improve performance, and how it lends itself better to alternative control flow structures.

> it's selfish to keep beautiful discoveries a secret.

It would be really fun to read what others found beautiful that they've never heard someone else mention.
JoshCole
·5 years ago·discuss
A crafty person here will draw on ideas like kalman filters and sensor fusion to notice that as the number of measurements increase you can gain precision even in the presence of an unreliable sensor.

This is very true and it might be where the bad intuition that having multiple unreliable sensors is good is coming from. Multiple noisy readings can be averaged to get a more reliable reading if the distribution of reading errors is normally distributed. You can take ten Norm(0, 10) and average them and the result of that will be a normal distribution with a standard deviation which is lower than the standard deviation of the distribution that we sampled from. See basic statistics for the e

There are a few reasons why this doesn't apply in this case:

1. The measurements aren't going to be of the same thing. At time step t, the state of the world is potentially different from t+1. Since we have one radar sensor averaging the results of the two sensor readings doesn't give us the true position. Kalman filters solve this with a dynamics function so this problem isn't something that is impossible to solve.

2. So lets say we solve it. Even if we did measure the same thing we have another problem. We don't have time to take advantage of the central limit theorem. Yes, multiple noisy readings of the same thing average to the true reading, but since we have only a split second to decide whether to slam on the break to avoid an accident we don't have the capacity to await convergence of the noisy sensor and noisy dynamic function to the true measurement. But lets say we did even though we don't.

3. The radar sensor isn't actually a normal distribution in terms of its noise. It's actually more accurate in certain low visibility conditions because it goes through occlusion, but less accurate given certain environments like going under an underpass. Since the noise isn't normally distributed you don't have the guarantees from statistics which you were hoping to rely on.
JoshCole
·5 years ago·discuss
Just to show you mathematically that they're right consider that if you have two sensors that are both measuring the same thing. One is Norm(mean=0, std=0.00001) and the other is Norm(mean=0, std=10). The true quantity is always zero in the real world. Given this scenario and these two senors you get the result of 0.11 and 11 as your return from the two sensors. Lets say we average the result of these two sensors. The average is farther from the true value than the first sensor was. The less reliable sensor is adding noise to our measurement. It isn't high utility.
JoshCole
·5 years ago·discuss
> When more sensors don't perform better than less sensors, either your hardware or your software is flawed.

Consider that 99 cameras plus one radar does not make a system perform better if the task is identifying whether there is the color blue in an image. If we add ten thousand radars to this situation it doesn't produce an improvement, in fact, it gets worse, because there is more power being used by the sensors and a lot more complexity.

> Removing a sensor from design because your system doesn't work speaks poorly of your product.

This is a convoluted way of saying that making improvements to things is bad. That is nonsensical.

> Even following that simplistic logic, if autopilot isn't safe, How could they dare not remove it?

They did remove it.
JoshCole
·5 years ago·discuss
From the keynote of CVPR. CVPR is the premier annual computer vision event comprising the main conference and several co-located workshops and short courses.

https://cvpr2021.thecvf.com/

https://www.youtube.com/watch?v=g6bOwQdCJrcCVPR
JoshCole
·5 years ago·discuss
Radar removal improved accuracy rather than harming it, they don't actually sell a car at the price point you listed. and inference from Tesla's award winning safety records suggests that Telsa does care about human life.

The factual content in your comment is decisively lacking.

Careless of you, I think.