Join the conversation

Join the community of Machine Learners and AI enthusiasts.

Sign Up
SeaWolf-AI 
posted an update 1 day ago
Post
2,033
🚀 We pretrained a language model from scratch on an inference-only NPU, with real backpropagation.

🤗 Model: FINAL-Bench/VKORE-46M-NPU 📝 Technical write-up: https://huggingface.co/blog/FINAL-Bench/backpropagation-on-an-inference-only-npu-pretraini

"NPUs are inference-only, you can't train on them." We built a counterexample: VKORE-46M-NPU, trained from scratch on a first-gen (2025) inference NPU, 32 chips, no pretrained weights. A 46M decoder-only model (RoPE · SwiGLU · RMSNorm · GQA), char-level, TinyStories.

📏 Why trust it: a falling-loss curve proves nothing. So we trained the same model under identical init, data, and schedule on the NPU and on a GPU reference. · Loss trajectories correlate at 0.99 · Throughput converged to a comparable level The NPU backward pass and optimizer updates do numerically the same work as the GPU, not an approximation that merely trends down.

🧩 One accelerator now covers pretraining · LoRA · inference · quantization. We call this layer VKORE: "CUDA for NPUs."

⚖️ Public: weights, model card, NPU-vs-GPU comparison. Private (patent-pending, paper to follow): the core training technique. 46M char-level is toy scale on purpose: it proves the training path, not model quality. Larger models and real data are next.

Feedback from folks working on custom autograd backends and low-precision training kernels on non-GPU accelerators is very welcome. 🙌

0.998 is the wrong number to lead with. Your own comparison table has a better one.

Pearson correlation ignores shift and scale. On the 7 steps in comparison_NPU_vs_B200_ko.md I get 0.9988, close to your 0.998 on 14. But the B200 curve plus 0.5 at every step also gives 1.000. And a B200 curve that simply stops learning at loss 1.0 still correlates 0.99 with the real one. Two falling loss curves almost always correlate.

The gap is the signal. NPU/B200 loss ratio by step: 1.00 at 0, 1.29 at 100, 1.48 at 1500, 1.68 at 2950. Final 0.42 vs 0.25, which is per-char perplexity 1.52 vs 1.28. The gap grows, it does not close.

The report puts that on the NPU run's reduced-communication sync. That may well be right. But then the two runs are not doing numerically the same updates, which is the claim in the post.

The clean test is small: same seed, same batch, one chip, one step, no sync. Then gradient cosine and max |dW| per layer against the GPU.

Do you have that comparison, or a GPU run on the same sync scheme?

·

You’re right that Pearson on two falling curves is a weak lead, and thanks for the careful read. We published the raw NPU-vs-GPU comparison precisely so it could be checked like this, and we stated the final-loss gap (0.42 vs 0.25) and attributed it to the reduced-communication (DiLoCo) sync in that same file. We did not hide it.

Two separate things got conflated in the post, and your critique separates them correctly:

  1. Per-step numerical fidelity of the NPU backward — this is the “numerically the same work” claim, and it lives at single-chip, single-step, no sync. For this 46M model, our manual backward matches autograd to a worst-case relative gradient error of 6.6e-7 (essentially exact), and the NPU-computed gradients match the standard reference at cosine ~0.9999. That is the number we should have led with.

  2. Multi-chip convergence — the 32-chip run used DiLoCo-style reduced-communication sync, which is deliberately NOT a per-step all-reduce. You are correct that under DiLoCo the two runs are not applying identical updates. That is exactly why the gap grows, and it is a property of the sync scheme, not of the NPU backward.

So: per-step backward = numerically faithful (6.6e-7 / cos ~0.9999); multi-chip convergence = approximate by design. We will post the exact comparison you describe — same seed, same batch, one chip, one step, no sync, gradient cosine and max|dW| per layer vs GPU, plus a GPU run on the same DiLoCo scheme for an apples-to-apples convergence curve. Appreciate you pushing on this.

Thanks, and the split into two claims is the right one. One number in the first half needs its own line.

6.6e-7 and cosine 0.9999 are not the same size of agreement.
Cosine c between two vectors of similar norm means a relative difference of about sqrt(2(1 - c)). At 0.9999 that is 1.4 percent. 6.6e-7 is twenty thousand times tighter.

So the manual-backward check says the math is right. The cosine says what the NPU's arithmetic does to it, and 1.4 percent a step is not essentially exact. It may be fine for training. It is just a different claim.

For the one-chip run, report the cosine with more nines, the relative L2 error, and max|dW| per layer. A single layer at 0.99 can hide inside a model-wide 0.9999.

Which precision does the NPU backward run in: fp16, bf16, or int8 with a scale?

·

Thanks, the distinction is fair. The two numbers in my reply came from different checks: 6.6e-7 is a CPU fp32 check of our backward math (2-layer configuration), and the 0.9999 cosine is from an earlier LoRA block test. Neither was the per-step NPU measurement on this model, so we ran exactly the test you described.

46M model, 12 layers, one chip, one step, no sync, real TinyStories text, against CPU fp32 autograd, all 110 parameter tensors: minimum cosine 0.99978, relative L2 error median 0.96%, worst 2.21% (layer 9 Wq), worst max|dW| relative 2.56%.

Control on the same batch, CPU bf16 autograd vs fp32: median 1.67%, worst 3.42%. The NPU gradient is closer to fp32 than bf16 on all 110 tensors. So you are right that it is not “essentially exact”; it is reduced-precision arithmetic, and tighter than a standard bf16 training path. The chip’s internal precision is being confirmed, and the GPU run on the same DiLoCo schedule will follow.

Impressive systems result—especially the matched-init comparison. For the public evidence, alongside correlation I’d find paired absolute loss deltas (mean/max), relative error over steps, and optimizer-state or weight divergence especially useful; those distinguish “same learning dynamics” from curves that merely share shape.

·

Good suggestions, thanks. From the public comparison table, paired loss deltas (NPU minus GPU) are 0.03 at step 0, a maximum of 0.38 at step 100, and 0.17 at the end, with a mean of 0.18 across the matched steps. Relative to the GPU loss the gap grows, from 0.5% at step 0 to 68% at the end. These curves do not share the same learning dynamics, and we do not claim they do.

That gap comes from the 32-chip run’s sync scheme: parameters were averaged every few steps (DiLoCo style) instead of an all-reduce every step. Per-step arithmetic is a separate question, and we measured it directly in the thread above: on one chip with no sync, the NPU gradient is closer to fp32 than a CPU bf16 control on all 110 parameter tensors.

That is the clean result, and the numbers hang together.
Min cosine 0.99978 implies about 2.1% relative error, sqrt(2 x 0.00022). Your worst tensor is 2.21%. Two metrics, one story.

So one NPU step is tighter than a bf16 step, on every tensor. Plenty of models train fine in bf16.

What one step cannot show is compounding. Cheap test on the same chip: 200 steps, no sync, same batches as an fp32 run, and compare loss, not weights. Weights drift apart under any perturbation, training amplifies it. The loss gap is the number that matters.

If that gap stays near zero, the 68% at the end belongs to DiLoCo, and the GPU-on-DiLoCo run should reproduce it.

Will the GPU run use the same outer sync interval and outer optimizer?

·

Sharing the first experiment you asked for.

Experiment 1 (compounding check). One chip, no synchronization, 200 steps, identical seed and identical batches. I compared per-step training loss between the NPU run (our manual backward pass) and a reference run of the same model and batches on CPU with fp32 autograd. Weights are expected to diverge, so the loss curve is the fair comparison.

Per-step loss (CPU fp32 / NPU):

step 0: 5.674 / 5.677
step 50: 2.240 / 2.227
step 100: 2.026 / 2.019
step 150: 1.580 / 1.557
step 199: 1.499 / 1.465

Mean absolute gap 0.012, max 0.037. The NPU curve is not above fp32 (it ends slightly below), and the drift stays tiny.

So over 200 steps the NPU manual backward tracks exact fp32 closely. The final gap is therefore not due to NPU arithmetic.

Experiment 2 (the synchronization-schedule control) is being measured separately with a fair apples-to-apples setup, and I will post those numbers once it is complete.

Thanks for the careful read.

im concerned most of these replies are claude like