feat: add Windows integrated GPU support via torch-directml (Intel/AMD iGPU) - #271
Open
RajeshKumar11 wants to merge 6 commits into
Open
feat: add Windows integrated GPU support via torch-directml (Intel/AMD iGPU)#271RajeshKumar11 wants to merge 6 commits into
RajeshKumar11 wants to merge 6 commits into
Conversation
Introduces device_utils.py with helpers to detect and work with any compute device uniformly: - get_device_type() — normalises device string to cuda/directml/mps/cpu - is_cuda_device() — True only for NVIDIA CUDA devices - is_directml_device() — True for Intel/AMD iGPU via torch-directml - can_pin_memory() — True only when target is a CUDA device - supports_bitsandbytes()— True only for CUDA (guards compression) - empty_cache() — device-agnostic VRAM/cache clear - get_free_memory_bytes()— device-agnostic memory query (-1 if unavailable) - is_directml_available()— detects torch-directml install at runtime Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces all CUDA-hardcoded calls with device-agnostic equivalents. - utils.py: clean_memory(device) uses empty_cache(device); compress/ uncompress accept device param; load_layer forwards device param - airllm_base.py: guards compression on non-CUDA with clear ValueError; prefetch stream only for CUDA; pin_memory gated by can_pin_memory(); BetterTransformer import wrapped in try/except for optimum >= 2.0 - profiler.py: LayeredProfiler accepts device param, uses get_free_memory_bytes() safe for DirectML/MPS/CPU
- test_device_utils.py: 19 unit tests for all device_utils helpers covering CUDA/DirectML/MPS/CPU paths; CUDA/MPS tests auto-skip when hardware is unavailable - test_directml.py: 8 integration tests verifying tensor ops on Intel/AMD iGPU via DirectML including the full AirLLM layer load/compute/unload cycle; entire suite skips when torch-directml is not installed - test_compression.py: wrap class with @unittest.skipUnless so tests skip gracefully on machines without NVIDIA CUDA; fix import path to airllm.utils (compress_layer_state_dict was never in airllm __init__)
- README.md: new "Windows Integrated GPU (Intel/AMD)" section with install steps, inference example, and notes on compression limitation; add iGPU link to nav header and table of contents; add v2.12.0 entry to Updates log - setup.py: add extras_require with 'directml' (torch-directml) and 'compression' (bitsandbytes) optional groups
Three breaking changes in transformers 5.x broke AirLLM on any device: 1. torch.inference_mode() → torch.no_grad() in the layer loop: set_module_tensor_to_device() cannot modify inference tensors created inside inference_mode; no_grad disables gradients without that restriction. 2. Pre-compute rotary position_embeddings before the layer loop: transformers >= 5.x LlamaDecoderLayer no longer computes cos/sin internally — they must be passed explicitly as position_embeddings=(cos, sin). A fresh LlamaRotaryEmbedding is instantiated from config on CPU and the (cos, sin) tensors are moved to the target device once, then sliced per layer in get_pos_emb_args(). 3. Decoder layer return type: tensor not tuple: transformers 5.x LlamaDecoderLayer.forward() returns a bare tensor while 4.x returned a tuple. The layer(…)[0] indexing was stripping the batch dimension, causing wrong shapes in every subsequent layer. Now handles both tuple (4.x) and tensor (5.x) returns. Verified: TinyLlama-1.1B-Chat-v1.0 runs end-to-end on Intel Iris Xe via DirectML and correctly answers "What is 2 + 2?" → "2 + 2 = 4". Also adds run_real_model_test.py: a real-hardware test script that downloads TinyLlama from HuggingFace and runs it layer-by-layer via AirLLM AutoModel.
RajeshKumar11
force-pushed
the
feat/integrated-gpu-directml
branch
from
March 19, 2026 09:28
75430b8 to
ab53f3a
Compare
…ard index Models <= ~7B (e.g. TinyLlama, Phi, Gemma-2B) are distributed as a single model.safetensors or pytorch_model.bin file with no shard-index JSON. AirLLM previously hard-asserted that model.safetensors.index.json must exist, making these models fail on first use. Changes in split_and_save_layers() (utils.py): - model.safetensors.index.json → handled (existing behaviour, now elif) - model.safetensors (no index) → NEW: reads tensor keys via safe_open header (no data loaded) and builds weight_map in-memory - pytorch_model.bin (no index) → NEW: loads state dict to extract key list - none of the above → raises FileNotFoundError with a clear message Also adds tests/test_single_file_model.py with 4 cases: - single model.safetensors splits correctly - single pytorch_model.bin splits correctly - sharded index path still works (regression guard) - missing weights raises FileNotFoundError
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #270
What this PR does
Adds support for Intel and AMD integrated GPUs on Windows via torch-directml, enabling AirLLM to run on laptops and desktops with no discrete NVIDIA GPU.
Also fixes three transformers 5.x compatibility bugs that broke inference on all devices (CUDA, MPS, CPU) — discovered while testing on iGPU.
Tested on: Intel Iris Xe Graphics — TinyLlama-1.1B correctly answers prompts end-to-end. 28 tests pass, 5 correctly skipped (CUDA/MPS guards).
Changes
New file:
air_llm/airllm/device_utils.pyCentral device abstraction module:
get_device_type(device)— normalises device strings to"cuda"/"directml"/"mps"/"cpu"is_cuda_device/is_directml_device/can_pin_memory/supports_bitsandbytesempty_cache(device)— device-agnostic cache flushget_free_memory_bytes(device)— safe memory query (returns -1 for non-CUDA)get_directml_device(index)— convenience wrapperair_llm/airllm/airllm_base.pydevice_utils; guardBetterTransformerimport withtry/except(optimum ≥ 2.0 removed it)ValueErrorwith clear message whencompression=is used on a non-CUDA devicetorch.inference_mode()→torch.no_grad()in the layer loop —set_module_tensor_to_device()cannot modify tensors created insideinference_mode(fixes all devices)position_embeddingsbefore the layer loop; pass viaget_pos_emb_args()— transformers ≥ 5.xLlamaDecoderLayerno longer computes cos/sin internally (fixes all devices)layer(...)[0]was stripping the batch dim (fixes all devices)is_cuda_device(device)instead of baredevice.startswith("cuda")pin_memorygated oncan_pin_memory(device)(CUDA only)clean_memory()calls passdeviceargumentair_llm/airllm/utils.pyclean_memory(device)usesempty_cache(device)instead oftorch.cuda.empty_cache()uncompress_layer_state_dict/compress_layer_state_dict/load_layerpassdevicethroughmodel.safetensorsandpytorch_model.binwithout a shard index (small models ≤ ~7B)air_llm/airllm/profiler.pyLayeredProfileracceptsdeviceparameter; usesget_free_memory_bytes(device)instead oftorch.cuda.mem_get_info()air_llm/setup.pyextras_require = {'compression': ['bitsandbytes'], 'directml': ['torch-directml']}README.mdNew tests (
air_llm/tests/)test_device_utils.pytest_directml.pytest_single_file_model.pytest_compression.pyUsage (Intel/AMD iGPU)
Related
PR #272 (
fix/single-file-model-support) splits out the single-file model fix as a standalone patch that can be merged independently.