jhj
A modern Nvidia GB200 only does about 40 tflop/s in fp64 for instance. You can emulate higher precision/dynamic range arithmetic with multiple passes and manipulations of lower precision/dynamic range arithmetic but without an insane number of instructions it won't meet all the IEEE 754 guarantees for instance.
Certainly if Nvidia wanted to dedicate much more chip area to fp64 they could get a lot higher, but fp64 FMA units alone would be likely >30 times larger than their fp16 cousins and probably 100s of times larger than fp4 versions.
Floating point is just an inefficient use of bits (due to excessive dynamic range), especially during training, so it will always be welcome there. Extreme quantization techniques (some of the <= 4-bit methods, say) also tend to increase entropy in the weights limiting the applicability of lossless compression, so lossless and lossy compression (e.g., quantization) sometimes go against each other.
If you have billions in dollars in inference devices, even reducing the number of devices you need for a given workload by 5% is very useful.
If you add an LZ-type compressor and have this be in the critical path for inference, then decompression will be a lot slower. It would be best to fuse decompression with the compute kernels (e.g., a GEMM that performs decompression on each tile before the arithmetic), and the simpler the decompression routine, the easier this will be.
Typical entropy of bfloat16 values seen in weights (and activations) are about 10-12 bits (only 65-75% or so of the value range is used in practice). Sign and mantissa bits tend to be incompressible noise.
This has been exploited several times before in the context of both classical HPC and AI, with lossless compression work from Martin Burtscher's lab (https://userweb.cs.txstate.edu/~burtscher/), fpzip from LLNL (https://computing.llnl.gov/projects/fpzip) and my library dietgpu from 2021 (https://github.com/facebookresearch/dietgpu) which we used to speed training on a large GPU cluster by about 10% wall clock time overall by losslessly compressing all data prior to send and decompressing upon receive (e.g., gradients, weights from backup, etc), which is still computing the same thing as it did before as it is lossless.
Also, rANS is more efficient and easier to implement in SIMD-like instruction sets than Huffman coding. It would reduce the performance latency/throughput penalties as well with DFloat11 (since we have to decompress before we do the arithmetic).
e.g., you make $200K in 2024 and $5 million in 2025 (which includes the RSU windfall). Assuming you pay at least 110% of what you paid in taxes in 2024 in 2025, you need not pay estimated tax or anything beyond statutory withholding amounts on the RSU windfall, and can just make up the 6 or 7 figures of tax owed at tax settlement time (e.g., by April 15/16 after the tax year in question). This is the optimal strategy, you can just park the money for tax owed in a close to as risk-free investment as possible in the meantime.
Statutory withholding rates might be higher; e.g., at my employer, if your RSU earnings are below $1 million, you can set your federal withholding as low as 22%. If your earnings are above $1 million, you are stuck with the 37% mandatory federal withholding rate (both done by sell to cover). This does not include per-state withholding minima, which can vary widely.
Absolute lowest cold here each year will be around -30 F / -34 C (there will be several nights in the winter where it gets below -20 F / -29 C), and absolute hottest it will ever be around 85 F / 29 C, but average annual temperature is about 35 F / 2 C. It can snow any month of the year here, with snow on the ground usually between November and mid May.
My house was built in 1968 and I have primarily resistive baseboard heating, with a large Mitsubishi mini-split installed by my home's previous owner mainly for air conditioning purposes in major rooms for a couple of weeks in the summer. I live at 6500 ft / 2000 m altitude, so even on the hottest summer days once the sun goes down it gets quite chilly and can get close to freezing, so it's really just for a few hours in the afternoon for a/c purposes. I otherwise use the heat pumps as baseline heat in the winter.
I'd like to put trust in heat pumps more because they are obviously more efficient (also as seen by my already low power bill), but lack of heat on certain days in the winter has serious implications here for home integrity, and while this might just be this one Mitsubishi model (though they are less than 5 years old), I haven't been left with a good opinion of heat pump design and repairability in general and am not tempted much to explore heat pumps further.
The heat pumps are rated to work down to -5 F / -21 C in the manual, but in practicality it's more like 15 F / -9 C otherwise they just spend a large part of their time defrosting. The models I have don't seem well engineered for reliability or maintenance either, there are important fuses hard-soldered to the main board that are not individually replaceable, and true enough in the middle of winter my HVAC technician and I had to bypass the blown fuses with an automotive fuse we had (same stats) attached with alligator clips, as it would take weeks or months to obtain a new $1500 (!) main circuit board from who knows where. On the other hand, resistive heating usually just works assuming you have power, and I also have two fireplaces as emergency backup if there's no power (though power lines are almost all buried here due to snow/ice anyways).
I really would like to see more emphasis on reliability and repairability rather than, like, SEER, HSPF, or COP ratings or whatever.
(I wrote the GPU half of Faiss and work with the people who wrote this paper).
> In this section, we show that L-Mul is more precise than fp8 e4m3 multiplications
> To be concise, we do not consider the rounding to nearest even mode in both error analysis and complexity estimation for both Mul and L-Mul
These two statements together are non-sensical. Sure, if you analyze accuracy while ignoring the part of the algorithm that gives you accuracy in the baseline you can derive whatever cherry-picked result you want.
The multiplication of two floating point values if you round to nearest even will be the correctly rounded result of multiplying the original values at infinite precision, this is how floating point rounding usually works and what IEEE 754 mandates for fundamental operations if you choose to follow those guidelines (e.g., multiplication here). But not rounding to nearest even will result in a lot more quantization noise, and biased noise at that too.
> applying the L-Mul operation in tensor processing hardware can potentially reduce 95% energy cost by elementwise floating point tensor multiplications and 80% energy cost of dot products
A good chunk of the energy cost is simply moving data between memories (especially external DRAM/HBM/whatever) and along wires, buffering values in SRAMs and flip-flops and the like. Combinational logic cost is usually not a big deal. While having a ton of fixed-function matrix multipliers does raise the cost of combinational logic quite a bit, at most what they have will probably cut the power of an overall accelerator by 10-20% or so.
> In this section, we demonstrate that L-Mul can replace tensor multiplications in the attention mechanism without any loss of performance, whereas using fp8 multiplications for the same purpose degrades inference accuracy
I may have missed it in the paper, but they have provided no details on (re)scaling and/or using higher precision accumulation for intermediate results as one would experience on an H100 for instance. Without this information, I don't trust these evaluation results either.
Kernels should almost never use local memory (except in arcane cases where you are using recursion and thus a call stack that will spill where an alternative non-recursive formulation would not really work).
> Many real-world applications, especially compute-bound kernels, need high occupancy to fully utilize the GPU’s resources
> while low-occupancy optimizations can be effective for specific workloads (e.g, memory-bound kernels)
I think this is almost exactly backwards, performant high compute intensity kernels (on a (fl)op/byte of memory traffic basis) tend to uniformly have low occupancy; look at a ncu trace of many kernels in cuBLAS or cuDNN for instance. You need a large working set of arguments in registers or in smem to feed scalar arithmetic or especially MMA units quickly enough as gmem/L2 bandwidth alone is not sufficient to achieve peak performance in many case. The only thing you need to do is to ensure that you are using all SMs (and thus all available scalar arithmetic or MMA units) which does not by itself imply high occupancy (e.g., a kernel that has 1 CTA per SM).
The simplest way to write a memory-bound kernel is to simply spawn a bunch of threads and perform load/stores from them and it isn't too hard to achieve close to peak this way, but even then depending upon the warp scheduler to rotate other warps in to issue more load/stores is inferior to unrolling loops, and you can also get close to peak mem b/w by using not too many SMs either through such unrolling, so even these need not have high occupancy.
(I've been Nvidia GPU programming for around 11 years and wrote the original pytorch GPU backend/tensor library, the Faiss GPU library, and contributed some stuff to cuDNN in its early days such as FFT convolution.)
https://www.nvidia.com/content/gtc-2010/pdfs/2238_gtc2010.pd...
I would also think in terms of latency hiding rather than just work parallelism (though latency hiding on GPUs is largely because of parallelism). This is the reason why GPUs have massive register files, because unlike modern multi-core CPUs, we omit latency reducing hardware (e.g., speculative execution, large caches, that out-of-order execution stuff/register renaming etc) and in order to fill pipelines we need to have many instructions outstanding, which means that the operands for those pending arguments need to remain around for a lot longer, hence the massive register file.
https://www.nytimes.com/2018/05/13/business/deadly-convenien...
To use something for this for IR rewriting directly by the model is certainly more risky (it's difficult to guarantee post-rewrite that you would be computing the same thing; at least for compiler passes and optimization options, many of which also perform IR rewrites, the compiler such as LLVM/gcc should already have a huge suite of test coverage anyways).
(I'm not a compiler person but I'm a researcher on the same team at Meta FAIR as the authors)
My house is insured for more than I bought both the land and house for, as suggested by State Farm themselves due to ludicrous construction costs.
The direct backyard of my house in Wyoming is Bridger-Teton National Forest, wooded mountainous wilderness for miles with its trees abutting my property. A wildfire in 2012 in the forest came within 1.3 miles of me. I’m insured by State Farm, pay substantially less percentage wise than most places in the country for home insurance and my rate went down this year by about $1K, go figure.
The interconnects are improving at a slower rate in general than compute on the CPU/GPU is and it can be exploited.
https://userweb.cs.txstate.edu/~burtscher/ https://computing.llnl.gov/projects/floating-point-compressi...
but it tends to be very application specific, where there tends to be high correlation / small deltas between neighboring values in a 2d/3d/4d/etc floating point array (e.g., you are compressing neighboring temperature grid points in a PDE weather simulation model; temperature differences in neighboring cells won't differ by that much).
In a lot of other cases (e.g., machine learning) the floating point significand bits (and sometimes the sign bit) tends to be incompressible noise. The exponent is the only thing that is really compressible, and the xor trick does not help you as much because neighboring values could still vary a bit in terms of exponents. An entropy encoder instead works well for that (encode closer to the actual underlying data distribution/entropy), and you also don't depend upon neighboring floats having similar exponents as well.
In 2022, I created dietgpu, a library to losslessly compress/decompress floating point data at up to 400 GB/s on an A100. It uses a general-purpose asymmetric numeral system encoder/decoder on GPU (the first such implementation of general ANS on GPU, predating nvCOMP) for exponent compression.
We have used this to losslessly compress floating point data between GPUs (e.g., over Infiniband/NVLink/ethernet/etc) in training massive ML models to speed up overall wall clock time of training across 100s/1000s of GPUs without changing anything about how the training works (it's lossless compression, it computes the same thing that it did before).
There also tend to not be as many people driving around slowly gawking on the roads themselves (unlike Zion or Yosemite, say), since most of the park doesn't have crazy vista views, it's mainly a high altitude, flat-ish volcanic plateau in the middle. The specific sites along the roads will have the traffic mostly.
Addition/subtraction in a logarithmic number system is way more expensive than what you would spend on multiplication, especially if you care about correctly rounded results, as the (hardware) LUTs required are rather big.
For Euclidean (L2) distance indexes where the vectors are partitioned based on geometry (e.g., pretty much every indexing type, including cell-probe like IVF, most forms of LSH, or graph based indices), query vectors can be naturally associated geometrically with candidate nearest neighbor vectors, so the distribution of queries doesn't matter as much.
For inner product, it's hard to do much better than spherical clustering (what one would usually do for cosine similarity, which is to project all vectors to the surface of a unit hypersphere, and searching for nearest neighbors via cosine similarity is exactly equivalent to L2 search). But, in general the maximum inner product in the indexed set may lie nowhere near to the projection of the query vector onto the surface of the hypersphere.
The maximum inner product for a query vector might be almost nearly perpendicular to the query vector (e.g., a very, very far out and almost perpendicular) versus a vector that is parallel to the query vector but with tiny norm. In two dimensions, an example could be (1, 0) as a query vector, but (1, 10^6) as a database vector (or vice versa). The inner product is 1 but the two vectors are very far apart in Euclidean distance. If you project the vectors to the unit 1-sphere, the query vector is still (1, 0) but the database vector now becomes (1 / sqrt(10^12 + 1), 10^6 / sqrt(10^12 + 1)) ~= (0.000000999..., 0.99999...) (apologies if there's an error here) which would also be in a very different cell if one were using a graph-based or IVF partitioning.
Neural search techniques do show some promise here though (say, using a neural net to predict which vector buckets to look at).
While traditional database indexing is also still an open-ended research problem (e.g., read amplification/write amplification tradeoffs and the like), it produces exact solutions. That isn't the case at all for vector indexing beyond brute-force search, or exact indexing like k-D/BSP trees which don't work well in high dimensions due to the curse of dimensionality.
There is no one algorithm which is "better" than others along all dimensions; instead, for a given setting you look and see which technique (or combination of techniques) would let you lie along the Pareto-optimal tradeoff curve between fidelity/speed/memory, and for the application, you decide which of these is most important.
LSH in industrial practice is only really useful for incredibly high-dimensional (think 100K+ dimensions) and/or massively sparse vectors (e.g., only 1K of those 100K dimensions have a non-zero value), or if latency is a very huge concern (e.g., online approximate self-attention of vectors). For dense vectors around 20-1000 dimensions, other techniques are better. The quality of results via LSH leaves much to be desired so I have not seen it used in most modern settings, but there is a huge literature on it as it is easier to prove things mathematically regarding its properties.
Graph-based methods (e.g., HNSW): These work best for intermediate sized vector databases (100K - 10M vectors or so) as they are very fast and have high quality of results, but the memory overhead is high (indexing structures). It is impractical to use it for massive-scale indexes (think 1 billion+ vectors, unless you shard the database into smaller pieces and query all together, but this is computationally expensive. If the query vector distribution differs substantially from the database distribution you tend to run into problems here too.
Cell-probe based methods (e.g., IVF): These are used for the largest databases (e.g., 1 billion - 1 trillion+ vectors; at least those where you are not simply sharding the database and still searching every shard) as they scale pretty well. The quality of results can leave a lot to be desired though, as the partitioning of the database into geometric cells and only searching some subset (n IVF cells, only searching ~sqrt(n) of those) will tend to have a hard upper limit on finding the true nearest neighbor (recall will saturate at around 30%, say). IVF is the foundation of Google ScaNN and is used heavily at FB/Meta as well.
These choices are independent of how vectors are encoded in the database (e.g., using product quantization, scalar quantization, raw floating point vectors, binarized vectors, etc).
There are some vector search problems (e.g., MIPS, or maximum inner product search, useful in recommendation problems or for things like approximate matrix multiplication/approximate self-attention) which still have no good solution (there is no metric space/geometry that makes sense here, and the query distribution usually varies quite widely from the database distribution).
"Neural search" or other ML-assisted search techniques (given a query vector, what partition of the database should you look in?) are improving over time as well.
This new paper of ours has a good overview of the tradeoffs involved https://arxiv.org/pdf/2401.08281.pdf
(I am the author of the GPU half of the Faiss library)
Also, distance comparisons are usually of the "ADC" (asymmetric distance comparison) form: the query vector is in full floating point format, and vectors, if quantized/compressed in the database, are effectively decompressed and compared in the full floating point domain. This is true even with PQ, as the distance between the query vector subspaces with each of the 2^n PQ codes for the same subspace are precomputed before comparison (and then the distance computation becomes a lookup-add based on the precomputed distance tables).
LSH techniques unlike PQ are more accurately described as an indexing technique, since the buckets into which vectors are placed are based on their encoding (via hashing/binarization) and are fully compared in that space.
"Use HNSW or Annoy for very large datasets where query speed is more important than precision": Graph-based methods have huge memory overhead and construction cost, and they aren't practical for billion-scale datasets. Also, they will usually be more accurate and faster than IVF techniques (as you would need to visit a large number of IVF cells to get comparable accuracy), though IVF can scale to trillion-sized databases without much overhead yet with reasonable speed/accuracy tradeoffs unlike other techniques. I'd say "use for medium-scale datasets where query speed is important, yet high accuracy is still desired and flat/brute-force indexing is impractical".
I don't really think so, at least not anytime soon while the hardware functionality continues to evolve so much, and while they seem to be concentrating on the high end devices/architecture rather than low-end stuff.
I've been more or less exclusively writing CUDA for the past decade in the AI/ML space (though have spent some time with OpenCL, Vulkan and other things along the way too). What a GPU is or should be I don't think has reached an evolutionary end yet. CUDA also is not a static thing, and it has co-evolved with the hardware, not being locked into some static industry standard with a boatload of annoying glExtWhatever dangling off of it. Over the past decade or so, Nvidia has introduced new ways that the register file can be used (Kepler shuffles), changed the memory model of GPUs and the warp execution model (to avoid deadlock/starvation by breaking the lockstep behavior somewhat), slowly changing the grid/CTA model (cf. cooperative groups, CTA clusters), adding more asynchronous components to the host APIs and the hardware (async DMAs), and has constantly changed the underlying instruction set, all of which leaks into CUDA in some way.
For (1), all of the indexing features of a typical RDBMS are overkill for IVF, where the only indexing you need is by IVF bucket, and then you simply sequentially scan and evaluate distances for everything in those buckets.
However, if you want to perform filtering based on other criteria (e.g., filtering based on metadata associated with each vector), then multiple column indexes could be useful with a RDBMS, as you can more efficiently extract just the vectors that meet criteria prior to a sequential scan (e.g., give me all vectors which have a date in the range between X and Y and whose name contains the string "red").
For (2), these algorithms would be inefficient to express in a typical RDBMS. While you can easily encode a graph in a RDBMS, walking the graph sequentially based on criteria is another matter, because each time you'd have to hit the disk (or in-memory cache) to find the next row to look at, then repeat. Latency could be an issue unless it's all in memory, and if it's all in memory, a RDBMS-type representation is overkill versus more simple pointer chasing in memory.
I guess it also depends upon latency / throughput needs (caching in memory on front of a database could help, but a pure in-memory vector index would be faster), persistence / fault tolerance / replication needs (in memory databases would need some kind of persistent store), or update needs (adding/removing vectors, though adding/removing vectors from an IVF or graph-based index becomes non-trivial if you add or remove too many vectors). Traditional databbases that have been around for a while might provide better guarantees on reliability.
(I'm the author of the GPU half of the Faiss library)