diff --git a/assets/contributors.csv b/assets/contributors.csv index a2f2ab49f7..3f27d03686 100644 --- a/assets/contributors.csv +++ b/assets/contributors.csv @@ -129,3 +129,6 @@ Anupras Mohapatra,Arm,,,, Tomas Agustin Gonzalez Orlando,Arm,tgonzalezorlandoarm,tgorlando,, Jai Adam Schrem,Arm,jai-adam-schrem,jai-adam-s-395bb1233,, Steve Jordahl,Rafay,,,, +Nii Osae Osae Dade,Mindbeam,StarkOsae,,, +Tony Morri,Mindbeam,tonymindbeamai,,, +Sayandip Pal,Mindbeam,sayandip-pal,,, diff --git a/content/install-guides/litespark-inference.md b/content/install-guides/litespark-inference.md new file mode 100644 index 0000000000..d50828f1a3 --- /dev/null +++ b/content/install-guides/litespark-inference.md @@ -0,0 +1,157 @@ +--- +additional_search_terms: +- BitNet +- ternary +- LLM +- inference +- CPU +- Arm +- Graviton +- Apple silicon +- Python + +layout: installtoolsall +minutes_to_complete: 10 +author: + - Nii Osae Osae Dade + - Tony Morri + - Sayandip Pal +multi_install: false +multitool_install_part: false +official_docs: https://github.com/Mindbeam-AI/Litespark-Inference +test_images: +- ubuntu:latest +test_link: null +test_maintenance: true +title: Litespark-Inference +description: Install Litespark-Inference on Arm or x86 Linux and Apple silicon macOS to run BitNet ternary LLMs on the CPU. +tool_install: true +weight: 1 +--- + +[Litespark-Inference](https://github.com/Mindbeam-AI/Litespark-Inference) +is an open-source CPU inference runtime for +[BitNet b1.58](https://arxiv.org/abs/2402.17764) ternary-weight LLMs. A +single `pip install` reads your CPU's feature flags and compiles the +right C++ kernel for it - NEON + SDOT on Arm, AVX-512/VNNI or AVX2+FMA +on x86. You do not pick the kernel; it picks itself. + +## What do I need before installing Litespark-Inference? + +- **Python 3.10 or newer.** Check with `python3 --version`. +- **A C++ toolchain** (`clang` or `g++`). Already present on most + developer machines; install steps per platform are below. +- **About 5 GB of free disk.** The BitNet-2B model downloads from + Hugging Face on first run. + +It is good practice to install into a clean virtual environment so the +install does not conflict with anything else on your machine: + +```console +python3 -m venv .venv +source .venv/bin/activate +python -m pip install --upgrade pip wheel setuptools +``` + +Then follow the section for your platform. + +## How do I install Litespark-Inference on Arm or x86 Linux? + +The released package builds the correct kernel for your CPU +automatically - AVX-512 with an AVX2+FMA fallback on x86, and NEON + +SDOT on Arm (Graviton 2/3/4, Ampere, Neoverse N1/N2/V1/V2, Raspberry +Pi 5). Install the C++ toolchain, then the package: + +```bash +sudo apt-get update +sudo apt-get install -y build-essential clang ninja-build git python3-pip +pip install litespark-inference +``` + +For Red Hat, Fedora, or RHEL, install the toolchain with `dnf` instead: + +```console +sudo dnf install -y gcc-c++ clang ninja-build git python3-pip +``` + +Confirm the package imports and reports the kernel selected for your CPU: + +```bash +python3 -c "import litespark_inference; print(litespark_inference.__version__)" +``` + +To inspect which kernel was built, run: + +```console +python -m litespark_inference.torchless info +``` + +The output ends with one of the following, depending on your CPU: + +```output +kernel : avx512 (torchless, extern "C" AVX-512/VNNI + OMP) +kernel : avx2 (torchless, extern "C" AVX2+FMA fallback + OMP) +kernel : neon (torchless, extern "C" NEON SDOT) +``` + +## How do I install Litespark-Inference on Apple silicon macOS? + +Apple's CPUs have NEON SDOT and Litespark-Inference uses it directly. +The only extra step versus Linux is installing `libomp` - Apple's +toolchain does not ship a built-in OpenMP runtime, and Litespark uses +OpenMP for multi-threading inside the kernel: + +```console +# Xcode command-line tools (one-time setup; no full Xcode required) +xcode-select --install + +# libomp via Homebrew +brew install libomp + +# Install the released package from PyPI +pip install litespark-inference +``` + +Verify the install: + +```console +python -m litespark_inference.torchless info +``` + +Expected output includes: + +```output +kernel : neon (torchless, extern "C" NEON SDOT) +OpenMP : True (max_threads=...) +``` + +If `OpenMP : False`, the build did not find Homebrew's `libomp`. The +most common cause is that Homebrew is installed under `/opt/homebrew` +(the Apple silicon default) but `pip install` ran in an environment that +hides it. Re-running `pip install litespark-inference` from a normal +shell usually fixes it. + +## How do I install from source? + +To modify the runtime or kernels, install from source instead of from +PyPI: + +```console +git clone https://github.com/Mindbeam-AI/Litespark-Inference.git +cd Litespark-Inference +pip install -e . +``` + +## Sanity-check + +On all platforms, the same one-liner generates text. The first run +downloads `microsoft/bitnet-b1.58-2B-4T-bf16` from Hugging Face (around +4.5 GB into `~/.cache/huggingface/hub`); later runs start instantly: + +```console +litespark-inference generate "Hello, world!" --max-tokens 16 +``` + +You are now ready to run BitNet-2B. Continue with the +[Accelerate LLM inference on Arm CPUs with Litespark-Inference](/learning-paths/laptops-and-desktops/litespark-inference/) +Learning Path. diff --git a/content/learning-paths/laptops-and-desktops/litespark-inference/01-introduction.md b/content/learning-paths/laptops-and-desktops/litespark-inference/01-introduction.md new file mode 100644 index 0000000000..1e44b61424 --- /dev/null +++ b/content/learning-paths/laptops-and-desktops/litespark-inference/01-introduction.md @@ -0,0 +1,73 @@ +--- +title: What is Litespark-Inference? +weight: 2 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## The short version + +Litespark-Inference is an open-source runtime that runs +ternary-weight language models - such as +[BitNet b1.58](https://arxiv.org/abs/2402.17764) - on the CPU you +already have. +No GPU. No CUDA wheel. No PyTorch installation. The dependency +footprint after `pip install` is `numpy`, `safetensors`, and +`tokenizers`. + +It runs on: + +| Platform | Kernel selected automatically | +|---|---| +| **Linux on x86_64** with AVX-512 (Intel Ice Lake+ / AMD Zen 4+) | AVX-512 + VNNI | +| **Linux on x86_64**, Intel Core Ultra (no AVX-512) | AVX-VNNI (256-bit) | +| **Linux on x86_64** without VNNI (AMD Zen 2-3, pre-Skylake-X Intel) | AVX2 + FMA fallback | +| **Linux on Arm (Graviton 2/3/4, Ampere, etc.)** | NEON + SDOT | +| **macOS on Apple silicon (M1/M2/M3/M4/M5)** | NEON + SDOT | + +A single `pip install` reads your CPU's feature flags and compiles the +right C++ source for you. You don't pick the kernel; it picks itself. +The [Litespark-Inference install guide](/install-guides/litespark-inference/) +covers the install step for each platform. + +## Why BitNet on the CPU + +BitNet b1.58 stores each weight as a value in `{-1, 0, +1}` and packs +four weights into one byte. That means: + +- The model file is around 6x smaller than the equivalent `bfloat16` + model (around 497 MB packed versus around 4,600 MB unpacked). +- Every matmul reduces to `int8` activation x ternary weight - exactly + what a CPU's SIMD dot-product instructions (SDOT on Arm, VNNI on + x86) are designed for. + +The net effect: a 2-billion-parameter model that fits in under 1 GB of +RAM and generates tokens at interactive speed on a normal laptop or +cloud CPU instance. + +The charts below show Litespark-Inference against a PyTorch baseline +across several Arm and x86 CPUs. Token-generation throughput is roughly +an order of magnitude higher, and resident memory is around 6x smaller, +on every platform tested. + +![Token-generation throughput, Litespark-Inference versus PyTorch, on Apple M5 Max, AMD Zen 4, and Intel Core Ultra 9#center](throughput-comparison.png "Cross-platform throughput comparison") + +![Resident memory, Litespark-Inference versus PyTorch, on Apple M5 Max, AMD Zen 4, and Intel Core Ultra 9#center](memory-comparison.png "Cross-platform memory usage comparison") + +## What you'll do in this Learning Path + +1. **Run BitNet-2B from the CLI in one line:** + `litespark-inference generate "Why is BitNet fast on CPU?" --max-tokens 64`. + +2. **Run the same model from a short Python script** using the + high-level `BitNet.from_pretrained(...).generate(...)` API. + +3. **Tune the embedding dtype** (`bf16` / `int8` / `int4`) to trade + memory for quality. + +4. **(Optional)** Run a head-to-head benchmark against `transformers` + with `torch.bfloat16` on the same machine, with memory, TTFT, + throughput, and energy-per-token numbers. + +The next chapter runs BitNet-2B from the CLI and from Python. diff --git a/content/learning-paths/laptops-and-desktops/litespark-inference/02-run.md b/content/learning-paths/laptops-and-desktops/litespark-inference/02-run.md new file mode 100644 index 0000000000..bde91c8e76 --- /dev/null +++ b/content/learning-paths/laptops-and-desktops/litespark-inference/02-run.md @@ -0,0 +1,93 @@ +--- +title: Run BitNet-2B +weight: 3 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +With Litespark-Inference installed (see the +[install guide](/install-guides/litespark-inference/)), you can generate +text right away. + +## The CLI (one line) + +```bash +litespark-inference generate "Why is BitNet fast on CPU?" --max-tokens 64 +``` + +What this does: + +1. Loads `microsoft/bitnet-b1.58-2B-4T-bf16` from the Hugging Face cache + (downloaded on first run, around 4.5 GB). +2. Tokenizes the prompt and runs it through the model in one batched + **prefill** call. +3. Greedy-decodes 64 new tokens, streaming each one to your terminal + as it is produced. + +Other useful CLI commands: + +```bash +# Quick health-check - what kernel, what threads, what model +litespark-inference info + +# Interactive chat (multi-turn, reuses KV cache across turns) +litespark-inference chat +``` + +## From Python (a few lines) + +If you want to embed Litespark-Inference in an application, the +recommended API is the high-level `BitNet` class - load the model, then +call `generate`: + +```python +from litespark_inference.torchless import BitNet + +# Auto-downloads from Hugging Face on first use. +bn = BitNet.from_pretrained("bitnet-2b") + +# chat=True applies the system + chat template and returns a clean +# instruction-following answer (omit it for a raw continuation). +print(bn.generate("Why is BitNet fast on CPU?", max_new_tokens=64, chat=True)) +``` + +That is the whole surface: `from_pretrained` loads the packed model and +owns the KV cache; `generate` runs the batched prefill plus +autoregressive decoding for you. There is no `torch` import at inference. + +## Embed dtype: pick your memory / quality trade-off + +The weight matrices are always 2-bit packed (that is what BitNet b1.58 +means). The one thing you can vary is the token-embedding table's +dtype - and that controls a big chunk of the model's resident memory: + +| Embed dtype | Resident memory | Quality | When to use | +|---|---|---|---| +| `bf16` | around 813 MB | Reference | Default for accuracy-sensitive work | +| `int8` | around 656 MB | Indistinguishable from `bf16` in practice | Good balance | +| **`int4`** | **around 573 MB** | Slight quality cost on rare tokens | **Recommended** - fastest load, smallest footprint | + +CLI: + +```bash +litespark-inference generate "Why is BitNet fast on CPU?" --embed-dtype int4 --max-tokens 64 +``` + +Python: + +```python +from litespark_inference.torchless import BitNet + +bn = BitNet.from_pretrained("bitnet-2b", embed_dtype="int4") +print(bn.generate("Why is BitNet fast on CPU?", max_new_tokens=64, chat=True)) +``` + +## What's next + +If you just wanted to run BitNet on the CPU, you are done - go build +something with it. + +If you want to **know how fast it actually is** versus PyTorch on the +same machine (and how much energy it uses), continue to the next chapter +on benchmarking. diff --git a/content/learning-paths/laptops-and-desktops/litespark-inference/03-benchmark.md b/content/learning-paths/laptops-and-desktops/litespark-inference/03-benchmark.md new file mode 100644 index 0000000000..d3b2325535 --- /dev/null +++ b/content/learning-paths/laptops-and-desktops/litespark-inference/03-benchmark.md @@ -0,0 +1,159 @@ +--- +title: Benchmark against PyTorch +weight: 4 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +{{% notice Note %}} +This chapter is optional. Skip it if you just want to use the product. +It exists so you can quantify *how much* faster, smaller, and more +energy-efficient Litespark-Inference is on your machine versus the +Hugging Face and PyTorch baseline. The script also installs PyTorch as a +side effect (multi-GB download), which is worth knowing before you +start. +{{% /notice %}} + +Installing the package also gives you the `litespark-benchmark` +command, which runs both backends on the same prompt and prints a +side-by-side comparison table. + +## One-shot benchmark + +```bash +litespark-benchmark \ + --inference --pytorch \ + --no-matrix \ + --threads $(nproc) \ + --output results.json +``` + +About 1-2 minutes for the Litespark side, plus a longer pass for the +PyTorch baseline. Output ends with: + +```output +====================================================================== +COMPARISON: Litespark vs PyTorch +====================================================================== + +Metric PyTorch Litespark Improvement +---------------------------------------------------------- +Memory (MB) 4,602 773 5.9x +TTFT (ms) 2,692.0 264.7 10.2x +Throughput (tok/s) 1.88 25.42 13.4x +``` + +The exact numbers depend on your CPU - the example above is from an +AMD Threadripper PRO 5965WX (Zen 3, 24 cores, no AVX-512). Apple +M-series and AWS Graviton 3/4 land in the same order of magnitude. + +For the most accurate benchmark, run it when no other heavy processes +are running. + +## Flag-by-flag breakdown + +| Flag | Why | +|---|---| +| `--inference` | Run the BitNet inference benchmark (`pp128` + `tg128`). | +| `--pytorch` | Also run the Hugging Face/PyTorch baseline and print the comparison table. **Multi-GB PyTorch download on first run.** | +| `--no-matrix` | Skip the raw matrix-shape sweep, which can take an hour on a large CPU. | +| `--threads N` | Use N OMP threads. By default, the runtime uses the system default number of threads. Set this manually for an `N`-thread benchmark. | +| `--output results.json` | Saves the full result as JSON for further analysis or charting. | + +## How throughput scales with threads + +Sweeping `--threads` shows how prefill (`pp128`) and token generation +(`tg128`) scale as you add cores. Prefill is compute-bound and keeps +climbing with more threads; token generation is more memory-bound and +flattens out earlier. The charts below show the scaling on three +representative CPUs. + +![Litespark-Inference thread scaling on Apple M5 Max#center](thread-scaling-apple-m5.png "Thread scaling on Apple M5 Max") + +![Litespark-Inference thread scaling on AMD EPYC 9R14#center](thread-scaling-amd-epyc.png "Thread scaling on AMD EPYC 9R14") + +![Litespark-Inference thread scaling on Intel Xeon Platinum 8488C#center](thread-scaling-intel-xeon.png "Thread scaling on Intel Xeon Platinum 8488C") + +## (Optional) Energy measurement + +If you want **joules per token** alongside the throughput numbers, add +`--power`: + +```bash +litespark-benchmark \ + --inference --pytorch \ + --no-matrix \ + --threads $(nproc) \ + --power --power-cooldown 10 \ + --output results.json +``` + +On Linux, `--power` reads `/sys/class/powercap/intel-rapl/.../energy_uj` +(also works on AMD CPUs via the same kernel module). Those counters are +root-only by default, so the script auto-elevates with `sudo` - you will +see one password prompt at the start of the run. Once it has the +counters, everything else runs as the original user; the output JSON is +chowned back to you at the end. `--power-cooldown` sets the pause, in +seconds, before each measured power sample so the machine can settle +between runs. + +The added rows in the comparison table: + +```output +Energy (J) 12096.21 952.11 12.7x +Energy/token (J) 94.5016 7.4383 12.7x +``` + +On Apple silicon, `--power` uses `powermetrics` for the energy reading. + +### Where `--power` works + +| Platform | Energy reading | +|---|---| +| Bare-metal Linux on Intel or AMD | Supported, via powercap / RAPL | +| Bare-metal Linux on Arm (Graviton metal, Ampere) | Depends on the platform - Graviton metal exposes it, most Arm boards do not | +| macOS Apple silicon | Supported, via `powermetrics` (script handles sudo automatically) | +| AWS EC2 non-metal instances | Not available - the hypervisor blocks MSR access; powercap zones are absent | +| WSL2 on Windows | Not available - same reason as EC2 (virtualized CPU) | + +If `--power` reports `available: false`, your platform does not expose +the counters; the throughput numbers are still correct. + +## Reading the JSON output + +`results.json` contains the same fields shown in the table plus the +per-run timing distribution and the CPU's detected feature flags: + +```json +{ + "system": { + "cpu_model": "AMD Ryzen Threadripper PRO 5965WX 24-Cores", + "architecture": "x86_64", + "simd_features": { + "avx512f": false, + "avx512vnni": false, + "avx_vnni": false, + "neon": false + } + }, + "benchmarks": { + "inference": { "kernel": "avx2-torchless", "threads": 24 }, + "pytorch_baseline": { "threads": 24 } + } +} +``` + +The `simd_features` block tells you which kernel actually ran - useful +when comparing across machines. + +## You're done + +That is the full benchmarking flow. From here you can: + +- Try different `--embed-dtype` values to see the memory/quality trade-off. +- Run on a different machine and compare - the JSON output makes + side-by-side charts easy. +- File an issue at the + [Litespark-Inference repo](https://github.com/Mindbeam-AI/Litespark-Inference) + if your numbers look off or your platform is not detected correctly. diff --git a/content/learning-paths/laptops-and-desktops/litespark-inference/_index.md b/content/learning-paths/laptops-and-desktops/litespark-inference/_index.md new file mode 100644 index 0000000000..cd04760177 --- /dev/null +++ b/content/learning-paths/laptops-and-desktops/litespark-inference/_index.md @@ -0,0 +1,112 @@ +--- +title: Accelerate LLM inference on Arm CPUs with Litespark-Inference + +description: Learn how to run BitNet-2B ternary LLMs fast on Arm CPUs with Litespark-Inference - no GPU, no PyTorch - and benchmark it against PyTorch for memory, speed, and energy. + +minutes_to_complete: 25 + +who_is_this_for: > + This is an introductory topic for developers who want to run a + large language model on CPU - no GPU, no PyTorch, no cloud account. + If you can `pip install` a package, you can run Litespark-Inference. + +learning_objectives: + - Run BitNet-2B from the `litespark-inference` CLI in one line, and + from Python in a few lines with the high-level `BitNet` API. + - Pick the right embed dtype (`bf16` / `int8` / `int4`) for the + memory versus quality trade-off you want. + - Benchmark Litespark-Inference head-to-head against `transformers` + with `torch.bfloat16` and read memory, time-to-first-token, + throughput, and energy-consumed-per-token results. + +prerequisites: + - A Linux machine (Arm or x86_64) or an Apple silicon macOS machine, + with Python 3.10 or later. Anything from a Raspberry Pi 5 to a + Threadripper PRO works - Litespark-Inference auto-detects your CPU + and picks the right kernel. + - Litespark-Inference installed using the + [Litespark-Inference install guide](/install-guides/litespark-inference/). + - About 5 GB of free disk for the BitNet-2B model that downloads on + first run. + +author: + - Nii Osae Osae Dade + - Tony Morri + - Sayandip Pal + +generate_summary_faq: true +rerun_summary: false +rerun_faqs: false + +### Tags +skilllevels: Introductory +subjects: ML +armips: + - Neoverse + - Cortex-A + - Cortex-X +operatingsystems: + - Linux + - macOS +tools_software_languages: + - Python + - C++ + - NEON + - SDOT + - SVE + - llama.cpp + +further_reading: + - resource: + title: "Litespark Inference For CPUs: Ultra-Fast SIMD Framework for Ternary (1.58-bit) Language Models" + link: https://arxiv.org/abs/2605.06485 + type: documentation + - resource: + title: "The Era of 1-bit LLMs: All Large Language Models are in 1.58 Bits (BitNet b1.58 paper)" + link: https://arxiv.org/abs/2402.17764 + type: documentation + - resource: + title: "BitNet: Scaling 1-bit Transformers for Large Language Models" + link: https://arxiv.org/abs/2310.11453 + type: documentation + - resource: + title: Litespark-Inference GitHub repository + link: https://github.com/Mindbeam-AI/Litespark-Inference + type: website + - resource: + title: Litespark-Inference on PyPI + link: https://pypi.org/project/litespark-inference/ + type: website + - resource: + title: microsoft/bitnet-b1.58-2B-4T model on Hugging Face + link: https://huggingface.co/microsoft/bitnet-b1.58-2B-4T + type: website + - resource: + title: llama.cpp GitHub repository + link: https://github.com/ggml-org/llama.cpp + type: website + +### FIXED, DO NOT MODIFY +# ================================================================================ +weight: 1 # _index.md always has weight of 1 to order correctly +layout: "learningpathall" # All files under learning paths have this same wrapper +learning_path_main_page: "yes" # This should be surfaced when looking for related content. Only set for _index.md of learning path content. +--- + +Litespark-Inference is an open-source CPU inference runtime for +ternary-weight language models, such as +[BitNet b1.58](https://arxiv.org/abs/2402.17764). +It targets the same job as `llama.cpp` for ternary models - load a +model, generate tokens fast on a normal CPU - but takes a different +implementation route. It is a small NumPy-based Python runtime +("torchless") that calls hand-written `extern "C"` matmul kernels through `ctypes`, +with one source file per architecture (NEON for Arm, AVX-512/VNNI or +AVX2+FMA for x86). + +This Learning Path assumes you have already installed Litespark-Inference +using the [Litespark-Inference install guide](/install-guides/litespark-inference/), +which auto-detects your CPU - Linux on x86_64, Linux on Arm (Graviton +2/3/4 or Ampere), or macOS on Apple silicon - and compiles the right +kernel for it. Here you will run BitNet-2B from the command line and +from Python, tune the embedding dtype, and (optionally) benchmark it +head-to-head against PyTorch on the same machine. diff --git a/content/learning-paths/laptops-and-desktops/litespark-inference/_next-steps.md b/content/learning-paths/laptops-and-desktops/litespark-inference/_next-steps.md new file mode 100644 index 0000000000..727b395ddd --- /dev/null +++ b/content/learning-paths/laptops-and-desktops/litespark-inference/_next-steps.md @@ -0,0 +1,8 @@ +--- +# ================================================================================ +# FIXED, DO NOT MODIFY THIS FILE +# ================================================================================ +weight: 21 # The weight controls the order of the pages. _index.md always has weight 1. +title: "Next Steps" # Always the same, html page title. +layout: "learningpathall" # All files under learning paths have this same wrapper for Hugo processing. +--- diff --git a/content/learning-paths/laptops-and-desktops/litespark-inference/memory-comparison.png b/content/learning-paths/laptops-and-desktops/litespark-inference/memory-comparison.png new file mode 100644 index 0000000000..581279d07d Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/litespark-inference/memory-comparison.png differ diff --git a/content/learning-paths/laptops-and-desktops/litespark-inference/thread-scaling-amd-epyc.png b/content/learning-paths/laptops-and-desktops/litespark-inference/thread-scaling-amd-epyc.png new file mode 100644 index 0000000000..c29df545af Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/litespark-inference/thread-scaling-amd-epyc.png differ diff --git a/content/learning-paths/laptops-and-desktops/litespark-inference/thread-scaling-apple-m5.png b/content/learning-paths/laptops-and-desktops/litespark-inference/thread-scaling-apple-m5.png new file mode 100644 index 0000000000..b26f98ea88 Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/litespark-inference/thread-scaling-apple-m5.png differ diff --git a/content/learning-paths/laptops-and-desktops/litespark-inference/thread-scaling-intel-xeon.png b/content/learning-paths/laptops-and-desktops/litespark-inference/thread-scaling-intel-xeon.png new file mode 100644 index 0000000000..db9d7065e0 Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/litespark-inference/thread-scaling-intel-xeon.png differ diff --git a/content/learning-paths/laptops-and-desktops/litespark-inference/throughput-comparison.png b/content/learning-paths/laptops-and-desktops/litespark-inference/throughput-comparison.png new file mode 100644 index 0000000000..37f2e63c8d Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/litespark-inference/throughput-comparison.png differ