Polars + Parquet is awesome for portability and performance. This post focused on python portability, but Polars has an easy-to-use Rust API for embedding the engine all over the place.
The best way to use text embeddings portably is with Parquet and Polars
31–40 of 61 posts
Re: The best way to use text embeddings portably is with Parquet and Polars
#32Re: The best way to use text embeddings portably is with Parquet and Polars
#33 df = (
pl.scan_parquet('hf://datasets/minimaxir/mtg-embeddings/mtg_embeddings.parquet')
.filter(
pl.col("type").str.contains("Sorcery"),
pl.col("manaCost").str.contains("B"),
)
.collect()
)Polars is awesome to use, would highly recommend. Single node it is excellent at saturating CPUs, if you need to distribute the work put it in a Ray Actor with some POLARS_MAX_THREADS applied depending on how much it saturates a single node.
Re: The best way to use text embeddings portably is with Parquet and Polars
#34You can save a huge amount of overhead just by base64 encoding the vectors, they aren't exactly human readable anyway.
I imagine the resulting file would only be approximately 33% larger than the pickle version.
Re: The best way to use text embeddings portably is with Parquet and Polars
#35Lots of great findings --- I'm curious if anyone knows whether it is better to pass structured data or unstructured data to embedding api's? If I ask ChatGPT, it says it is better to send unstructured data. (looking at the authors github, it looks like he generated embeddings from json strings) My use case is for jsonresume, I am creating embeddings by sending full json versions as strings, but I've been experimentin…
I have a huge vector database that gets updated/regenerated from a personal knowledge store (markdown library). Since the user is most likely to input a comparison query in the form of a question "Where does X factor into the Y system?" - I use a small 7b parameter LLM to pregenerate a list of a dozen possible theoretical questions a user might pose to a given embedding chunk. These are saved as 1536 dimension sized embeddings into the vector database (Qdrant) and linked to the chunks.
The real question you need to ask is - what's the input query that you'll be comparing to the embeddings? If it's incoming as structured, then store structured, etc.
I've also seen (anecdotally) similarity degradation for smaller chunks as well - so keep that in mind as well.
Re: The best way to use text embeddings portably is with Parquet and Polars
#36Security: absolutely.
Portability: who cares? Frameworks move so quickly that unless you carry your whole dependency graph between machines you will not get bit compatible results with even minor version changes. It's a dirty secret that no one seems to want to fix or care about.
In short: everything is so fucked that pickle + conda is more than good enough for whatever project you want to serve to >10,000 users.
Re: The best way to use text embeddings portably is with Parquet and Polars
#37I have a minilm + pooling + svm classifier which works pretty well for some things (topics, "will I like this article?") but doesn't work so well for sentiment, emotional tone and other things where the order of the words matter. I'm planning to upgrade my current classifier's front end to use ModernBert and add an LSTM-based back end that I think will equal or beat fine-tuned BERT and, more importantly, can be trained reliably with early stopping. I'd like to open source the thing, focused on reliability, because I'm an application programmer at heart.
I want it to provide an interface which is text-in and labels-out and hide the embeddings from most users but I'm definitely thinking about how to handle them, and there's the worse problem here that the LSTM needs a vector for each token, not each document, so text gets puffed up by a factor of 1000 or so which is not insurmountable (1 MB of training text puffs up to 1 GB of vectors)
Since it's expensive to compute the embeddings and expensive to store them I'm thinking about whether and how to cache them, considering that I expect to present the same samples to the trainer multiple times and to do a lot of model selection in the process of model development (e.g. what exact shape LSTM to to use) and in the case of end-user training (it will probably try a few models, not least do a shootout between the expensive model and a cheap model)_
[1] think of a "magic magic marker" which learns to mark up text the same way you do; this could mark "needless words" you could delete from a title, parts of speech, named entities, etc.
Re: The best way to use text embeddings portably is with Parquet and Polars
#38If you host your own embedding model, then you can transmit numpy float32 compressed arrays as bytes, then decode back into numpy arrays.
Personally I prefer using SQLite with usearch extension. Binary vectors then rerank top 100 with float32. It’s about 2 ms for ~20k items, which beats LanceDB in my tests. Maybe Lance wins on bigger collections. But for my use case it works great, as each user has their own dedicated SQLite file.
For portability there’s Litestream.
Re: The best way to use text embeddings portably is with Parquet and Polars
#391. You don't really care too-much about accessing subsets of columns
2. You can't easily append stuff to closed Parquet files.
3. Batched-row access is presumably slower due to lower cache-hits.
It's okay for map-reduce style stuff where this doesn't matter, but in ML these limitations are an annoyance.
HDF5 (or Zarr, less portably) solves some/many of these issues but it's not quite a settled affair.
Re: The best way to use text embeddings portably is with Parquet and Polars
#40I was doing some time series calculations, simple equity price adjustments basically, in Polars and my two thoughts were:
- WTF, I can actually read the code and test it.
- it's running so fast it seems like it's broken.