Committing changes to a 130GB Git repository without full checkouts [video] (youtube.com)
The burden of checking out and building snapshots from diff history is now borne by localhost, but that may change, as mentioned in the video. Smart navigation of git history from the nearest available snapshots, building snapshots with Spark, and other ways to save on data transfer and compute are being evaluated. This paradigm enables hibernating or cleaning up history on S3 for datasets no longer necessary to create snapshots, like those that are deleted, if snapshots of earlier commits are not needed. Individual data entries could also be removed for GDPR compliance using versioning on S3 objects, orthogonal to git.
The prototype already cures the pain point I built it for: it was impossible to (1) uniquely identify and (2) make available behind an API multiple versions of a collection of datasets and config parameters, (3) without overburdening HDDs due to small, but frequent changes to any of the datasets in the repo and (4) while being able to see the diffs in git for each commit in order to enable collaborative discussions and reverting or further editing if necessary. Some background: I am building natural language AI algorithms (a) easily retrainable on editable training datasets, meaning changes or deletions in the training data are reflected fast, without traces of past training and without retraining the entire language model (sounds impossible), and (b) that explain decisions back to individual training data. LLMs have fixed training datasets, whereas editable datasets call for a system to manage data efficiently, plus I wanted to have something that integrates naturally with common, tried and tested tools such as Git, S3, and MySQL, hence the Data Manager.
I am considering open-source: is that the best way to go? Which license to choose?
17 comments
[ 2.9 ms ] story [ 37.6 ms ] threadOr maybe even if Git offered zstd compression would be cool too.
Doesn’t mean those deflate trees are optimal, as you can see with tools like OxiPNG optimizing the deflate compression to reduce png file sizes by about half.
The same optimization could be applied to git blobs in theory, it would be cool if there was a tool that did that.
——
My second point was more about if git was upgraded to add a new compression algorithm like zstd instead of Deflate, like switching the hash algorithm from SHA-1 to SHA-2 (though if I was in charge, I’d go with Blake3 because it’s far faster)
While you don't need the ten million rows to commit each new thousand rows, they are needed upon merging in order to detect conflicts. Object content referenced by S3 pointers is fetched if and when needed, but the git objects themselves are fetched since they are really small. It is neither partial nor shallow clone strictly, as all the objects and trees are downloaded in the current implementation, but the S3 pointers enable similar delaying and filtering behavior, like with DVC.
Sorry if the repo size is unclear, hope this is better: ~180 kB: current state at the branch head, includes pointers to S3 (exact size depends upon packs and indices), plus full history, also with pointers ~890 MB: current state at the branch head, after downloading all files referenced by pointers in the Git history from S3, plus full history, with pointers ~130 GB: commit history, this is what the repo would weigh on DVC or Git LFS, this repo corresponds to a use case with many small updates
With increasing repo size (even when the 2nd, 890 MB state, increases in size, let alone the fully materialized history), this enables working on the 1st (kBs) and still commit changes.
I'd be curious to hear what features you are missing. We have repositories that would be as big as 100GB if you downloaded all large files for the full history, but I guess I don't see why you would want do that?
If I check out head of my repo and don't filter anything, it's a couple GBs.
Inside the azure blob storage container that backs our LFS API server, there's probably terabytes of data. It's really very very much.
We don't have any performance problems. One API instance can handle it. Of course we did make sure to implement it well... It's Uvicorn/Starlette, all IO is async and all CPU "intensive" work like JSON (de)serialization runs in a background threadpool.
In our case though we don't frequently change files, we just get lots and lots of new big files coming in all the time.
Moving head, as in, to check out another branch locally? Somewhat regularly I guess. I suppose you're wondering about performance in that scenario? It's usually quite good since git-lfs does some local caching as well. I've never needed to wait longer than a couple of seconds. I'm usually on a wired 1000/1000 Mbit optic fibre connection, and transfers are directly to and from an azure blob storage container (the LFS API server only generates download and upload URLs, it intentionally doesn't transfer any data), with parallel connections and chunking etc, so it doesn't really get any better than that. And all of that is out of the box functionality too. :)
Yes I meant either checking out other branches locally, or in the general case pointing to another branch to indicate to any services to make data from that branch available to wherever it's consumed. I am assuming that each incoming new file is then added to data pipelines, possibly just a few. Sounds like you are in the sweet spot where you have the speed you want and, given unfrequent changes, you are fine with the versions taking up terabytes on Azure, since they are mostly new data.