vgel / repeng

A library for making RepE control vectors
https://vgel.me/posts/representation-engineering/
MIT License
435 stars 31 forks source link

Alternatives to PCA, such as umap #27

Open Hellisotherpeople opened 4 months ago

Hellisotherpeople commented 4 months ago

There's a whole large body of work on dimensionality reduction which handles non linearity better - i.e. UMAP. https://umap-learn.readthedocs.io/en/latest/

Is it simple to just "drop" this in place of PCA and get theoretically better results? If not, why?

what about other things, like NMF https://en.wikipedia.org/wiki/Non-negative_matrix_factorization ?

vgel commented 3 months ago

Playing with UMAP currently! I have it working but it's pretty funky, needs small coefficients. Doesn't seem to be a huge improvement over PCA currently, but it's possible the way I'm doing it isn't ideal. Might include it experimentally in the upcoming release!

(Generating a vector with UMAP is also ~30x slower than PCA currently.)

vgel commented 3 months ago

image image

Hellisotherpeople commented 3 months ago

Very interesting!

Given the issues you describe with performance of training, there is a CuML GPU implementation of UMAP (and a lot of other dimensionality reduction algorithms which could be offered) - https://docs.rapids.ai/api/cuml/stable/api/#umap - certainly a larger dependency chain but these days everyone's accepted nvidia's stack as being mandatory so it might be good to make optional at least.

I think there is some tuning you can do with base UMAP's hyperparamaters to improve speed and possibly the quality of the generated control vectors. A UMAP expert would be able to look over that and make sure it's set "correctly" given the data - unfortunately that is not me (and likely fewer than 100 of them exist in the world).

As far as to why it requires smaller coefficients and why the performance may be hard to quantify as better - I'd love to see some analysis about this from others in the community, or even the UMAP creator himself (or at least one of the aformentioned 100)

I'm extremely appreciative that you have implemented it yourself and tried it. Very happy to see such rapid response and that it might even be made available to others. Thank you!!!

vgel commented 2 months ago

umap is now experimentally supported as an (undocumented) option in #34 — use ControlVector.train(..., method="umap"), and ensure the umap-learn package is installed.

vgel commented 2 months ago

Please feel free to use this issue to continue discussing umap and potential improvements! I'm not sure if the current method is the ideal usage of it.

thiswillbeyourgithub commented 1 month ago

Thanks @vgel for all this.

I don't have a GPU and have little free time for quite some time still but I'm still very curious as to wether nonlinear dim reduction work "better".

Here are a few thoughts:

  1. There are tons of dimred algorithm. For example pacmap
  2. Each algorithm has usually lots of parameters, giving a lot of room for experiment. So it might be better to have the "method" argument accept a callable, taking as input the "train" var and be stored in "directions[layer]", offering maximum flexibility at seemingly little coding cost.
  3. I'm especially interested in the effect of gradually changing the thresholds between local and global focus of those algorithm. For example in the umap API we can tune the densmap parameter.
  4. Or hybrid approaches: use PCA for the rough direction, then add the vector * 0.1 of the umap transformed with a focus on local relationships. Also try with global focus.
  5. Also, maybe PCA starts working quickly (=with few examples) but the cost is a greater loss in benchmark, whereas nonlinear dimred have less sensitivity (=need more examples) but greater specificity (=reducing those directions have less side effects)
  6. In any case, those algorithms can be greatly speedup by first taking the PCA transformation over say 50 dimensions and then applying the non linear dimension algorithm over the transform. This might not defeat the purpose entirely and retain the hypothetical gains. AFAIK it's common practice as PCA allows checking we retain enough of the variance to make sure we're not screwing up the data.
  7. Maybe it would be a well spend effort to constitude a standardized test rig before tuning all those things. These days I'm thinking about the recent papers about abliteration, well summarized into this blog post that nicely uploaded easy to use datasets with good and bad exemples of refusals. That might be the quickest way to create our own mini benchmark.

Anyway, I won't have time for about 6-12 months but may do a PR eventually.

If anyone's interested, please share your findings, especially negative results!

thiswillbeyourgithub commented 1 month ago

Addendum to my thoughts above (I hope nobody will mind!):

  1. Instead of taking all the N samples and doing a 1 dimension PCA to deduce dimension, I'm thinking of another way:
    • Outline:
    • Take the N samples
    • Do a Kmeans with n_cluster=k
    • Split the N samples into the k roughly equal clusters (KMeans has the nice property to tend to make even size clusters).
    • Then do the 1D PCA over each cluster.
    • Now for each inference: compute the distance between the current activation, and each cluster centroid and normalize these distances so they sum to 1.
    • Now apply to the activation the k directions (1 per cluster), weighted by the distances.
    • All resemblance to mixture of experts is intentional: the distances is a bit like the routing network, and the idea is to optimize the tradeoff between how effective representative engineering is without being too rough (=risk of side effects).