mirror of
				https://github.com/huggingface/kernels.git
				synced 2025-11-04 05:55:32 +08:00 
			
		
		
		
	Compare commits
	
		
			2 Commits
		
	
	
		
			v0.10.2
			...
			doc-kernel
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| f578f172ea | |||
| dac834fc68 | 
							
								
								
									
										8
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							@ -51,15 +51,11 @@ jobs:
 | 
			
		||||
        run: uv run mypy src/kernels
 | 
			
		||||
 | 
			
		||||
      - name: Run tests
 | 
			
		||||
        env:
 | 
			
		||||
          HF_TOKEN: ${{ secrets.HF_TOKEN }}
 | 
			
		||||
        run: |
 | 
			
		||||
          uv run pytest tests
 | 
			
		||||
 | 
			
		||||
      - name: Run staging tests
 | 
			
		||||
        env: 
 | 
			
		||||
          HF_TOKEN: ${{ secrets.HF_STAGING_TOKEN }}
 | 
			
		||||
        run: |
 | 
			
		||||
          HUGGINGFACE_CO_STAGING=true uv run pytest --token -m "is_staging_test" tests/
 | 
			
		||||
 | 
			
		||||
      - name: Check kernel conversion
 | 
			
		||||
        run: |
 | 
			
		||||
          uv pip install wheel
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,6 @@
 | 
			
		||||
# FAQ
 | 
			
		||||
 | 
			
		||||
## Kernel layers
 | 
			
		||||
 | 
			
		||||
### Why is the kernelization step needed as a separate step?
 | 
			
		||||
## Why is the kernelization step needed?
 | 
			
		||||
 | 
			
		||||
In earlier versions of `kernels`, a layer's `forward` method was replaced
 | 
			
		||||
by `use_kernel_forward_from_hub` and `replace_kernel_forward_from_hub`.
 | 
			
		||||
@ -13,29 +11,3 @@ on data-dependent branching.
 | 
			
		||||
 | 
			
		||||
To avoid branching, we have to make dispatch decisions ahead of time,
 | 
			
		||||
which is what the `kernelize` function does.
 | 
			
		||||
 | 
			
		||||
### Why does kernelization only replace `forward` methods?
 | 
			
		||||
 | 
			
		||||
There are some other possible approaches. The first is to completely
 | 
			
		||||
replace existing layers by kernel layers. However, since this would
 | 
			
		||||
permit free-form layer classes, it would be much harder to validate
 | 
			
		||||
that layers are fully compatible with the layers that they are
 | 
			
		||||
replacing. For instance, they could have completely different member
 | 
			
		||||
variables. Besides that, we would also need to hold on to the original
 | 
			
		||||
layers, in case we need to revert to the base layers when the model
 | 
			
		||||
is `kernelize`d again with different options.
 | 
			
		||||
 | 
			
		||||
A second approach would be to make an auxiliary layer that wraps the
 | 
			
		||||
original layer and the kernel layer and dispatches to the kernel layer.
 | 
			
		||||
This wouldn't have the issues of the first approach, because kernel layers
 | 
			
		||||
could be similarly strict as they are now, and we would still have access
 | 
			
		||||
to the original layers when `kernelize`-ing the model again. However,
 | 
			
		||||
this would change the graph structure of the model and would break use
 | 
			
		||||
cases where programs access the model internals (e.g.
 | 
			
		||||
`model.layers[0].attention.query_weight`) or rely on the graph structure
 | 
			
		||||
in other ways.
 | 
			
		||||
 | 
			
		||||
The approach of `forward`-replacement is the least invasive, because
 | 
			
		||||
it preserves the original model graph. It is also reversible, since
 | 
			
		||||
even though the `forward` of a layer _instance_ might be replaced,
 | 
			
		||||
the corresponding class still has the original `forward`.
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
[project]
 | 
			
		||||
name = "kernels"
 | 
			
		||||
version = "0.10.2"
 | 
			
		||||
version = "0.10.1.dev0"
 | 
			
		||||
description = "Download compute kernels"
 | 
			
		||||
authors = [
 | 
			
		||||
  { name = "OlivierDehaene", email = "olivier@huggingface.co" },
 | 
			
		||||
@ -12,7 +12,7 @@ license = { text = "Apache-2.0" }
 | 
			
		||||
readme = "README.md"
 | 
			
		||||
requires-python = ">= 3.9"
 | 
			
		||||
dependencies = [
 | 
			
		||||
  "huggingface_hub>=0.26.0,<2.0",
 | 
			
		||||
  "huggingface_hub>=0.26.0,<1.0",
 | 
			
		||||
  "packaging>=20.0",
 | 
			
		||||
  "pyyaml>=6",
 | 
			
		||||
  "tomli>=2.0; python_version<'3.11'",
 | 
			
		||||
 | 
			
		||||
@ -5,4 +5,3 @@ markers =
 | 
			
		||||
    darwin_only: marks tests that should only run on macOS
 | 
			
		||||
    xpu_only: marks tests that should only run on hosts with Intel XPUs
 | 
			
		||||
    token: enable tests that require a write token
 | 
			
		||||
    is_staging_test: Marks tests that should only run on a staging environment
 | 
			
		||||
 | 
			
		||||
@ -7,12 +7,11 @@ from pathlib import Path
 | 
			
		||||
from typing import List
 | 
			
		||||
 | 
			
		||||
import pytest
 | 
			
		||||
from huggingface_hub import delete_repo, model_info
 | 
			
		||||
from huggingface_hub import model_info
 | 
			
		||||
 | 
			
		||||
from kernels.cli import upload_kernels
 | 
			
		||||
 | 
			
		||||
REPO_ID = "valid_org/kernels-upload-test"
 | 
			
		||||
 | 
			
		||||
REPO_ID = "kernels-test/kernels-upload-test"
 | 
			
		||||
 | 
			
		||||
PY_CONTENT = """\
 | 
			
		||||
#!/usr/bin/env python3
 | 
			
		||||
@ -69,32 +68,7 @@ def get_filenames_from_a_repo(repo_id: str) -> List[str]:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.token
 | 
			
		||||
@pytest.mark.is_staging_test
 | 
			
		||||
def test_kernel_upload_works_as_expected():
 | 
			
		||||
    with tempfile.TemporaryDirectory() as tmpdir:
 | 
			
		||||
        path = f"{tmpdir}/build/torch-universal/upload_test"
 | 
			
		||||
        build_dir = Path(path)
 | 
			
		||||
        build_dir.mkdir(parents=True, exist_ok=True)
 | 
			
		||||
        script_path = build_dir / "foo.py"
 | 
			
		||||
        script_path.write_text(PY_CONTENT)
 | 
			
		||||
        upload_kernels(UploadArgs(tmpdir, REPO_ID, False))
 | 
			
		||||
 | 
			
		||||
    repo_filenames = get_filenames_from_a_repo(REPO_ID)
 | 
			
		||||
    assert any(str(script_path.name) for f in repo_filenames)
 | 
			
		||||
    delete_repo(repo_id=REPO_ID)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.token
 | 
			
		||||
@pytest.mark.is_staging_test
 | 
			
		||||
def test_kernel_upload_deletes_as_expected():
 | 
			
		||||
    with tempfile.TemporaryDirectory() as tmpdir:
 | 
			
		||||
        path = f"{tmpdir}/build/torch-universal/upload_test"
 | 
			
		||||
        build_dir = Path(path)
 | 
			
		||||
        build_dir.mkdir(parents=True, exist_ok=True)
 | 
			
		||||
        script_path = build_dir / "foo_2025.py"
 | 
			
		||||
        script_path.write_text(PY_CONTENT)
 | 
			
		||||
        upload_kernels(UploadArgs(tmpdir, REPO_ID, False))
 | 
			
		||||
 | 
			
		||||
    repo_filenames = get_filenames_from_a_repo(REPO_ID)
 | 
			
		||||
    filename_to_change = get_filename_to_change(repo_filenames)
 | 
			
		||||
 | 
			
		||||
@ -112,4 +86,3 @@ def test_kernel_upload_deletes_as_expected():
 | 
			
		||||
    assert not any(
 | 
			
		||||
        str(filename_to_change) in k for k in repo_filenames
 | 
			
		||||
    ), f"{repo_filenames=}"
 | 
			
		||||
    delete_repo(repo_id=REPO_ID)
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user