Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
8b2cf0e
feat: make system a part of kernels upload.
sayakpaul Feb 17, 2026
373debe
documentation in the writing kernels tutorial.
sayakpaul Feb 17, 2026
4c0fba2
remove stuff from upload.
sayakpaul Feb 25, 2026
b1931f5
refactor card commands and update tests.
sayakpaul Feb 25, 2026
5f0464a
better variable naming.
sayakpaul Feb 25, 2026
69a14af
add test to check existing content is preserved.
sayakpaul Feb 25, 2026
6f7a606
Merge branch 'main' into kernel-docs-followups
sayakpaul Feb 25, 2026
cc3cd23
make card upload a part of upload command.
sayakpaul Feb 25, 2026
4ba68fe
fix exists call.
sayakpaul Feb 25, 2026
49426c5
fix mypy.
sayakpaul Feb 26, 2026
54bbec9
Merge branch 'main' into kernel-docs-followups
sayakpaul Feb 26, 2026
36d502e
fix description entry and upload test.
sayakpaul Feb 27, 2026
734b440
updates.
sayakpaul Feb 27, 2026
4956809
doc updates.
sayakpaul Feb 27, 2026
ce5389e
simply args.
sayakpaul Feb 27, 2026
d6f40af
fix arg name
sayakpaul Feb 27, 2026
e99e5d1
move kernel card utils to cli module and jinja2 to toml.
sayakpaul Feb 27, 2026
9f76181
remove jinja2 imports.
sayakpaul Feb 27, 2026
f47a029
serialize in the root.
sayakpaul Feb 27, 2026
a23e11a
move around and fix tests
sayakpaul Feb 27, 2026
ade9c12
reviewer feedback.
sayakpaul Feb 28, 2026
35a8c5a
up
sayakpaul Feb 28, 2026
f3ae697
fmt.
sayakpaul Mar 3, 2026
5f38719
Apply suggestions from code review
sayakpaul Mar 3, 2026
a462c86
parse repo id from the build.toml when available.
sayakpaul Mar 3, 2026
ffa5cf7
mypy is the bane of my life.
sayakpaul Mar 3, 2026
616aa26
Merge branch 'main' into kernel-docs-followups
sayakpaul Mar 5, 2026
03d2c3d
okay
sayakpaul Mar 5, 2026
6dc694c
Merge branch 'main' into kernel-docs-followups
sayakpaul Mar 6, 2026
3a025d9
Merge branch 'main' into kernel-docs-followups
sayakpaul Mar 10, 2026
f40f3cb
repo_id should be parsed from build.toml and not from the user.
sayakpaul Mar 10, 2026
1459da9
up
sayakpaul Mar 11, 2026
407dcd4
make card init a part of kernels init.
sayakpaul Mar 11, 2026
e457639
remove init-card.
sayakpaul Mar 11, 2026
10cf0ec
fix
sayakpaul Mar 11, 2026
aee6a9d
Update docs/source/builder/writing-kernels.md
sayakpaul Mar 11, 2026
1e8b4d3
update to docs.
sayakpaul Mar 11, 2026
394ae8e
remove card docs.
sayakpaul Mar 11, 2026
5b52a52
up
sayakpaul Mar 11, 2026
916df0e
Merge branch 'main' into kernel-docs-followups
sayakpaul Mar 11, 2026
12b12c1
Merge branch 'main' into kernel-docs-followups
sayakpaul Mar 12, 2026
28f8abc
add a note on version.
sayakpaul Mar 12, 2026
dc9a01f
empty
sayakpaul Mar 12, 2026
8db442f
fix test
sayakpaul Mar 12, 2026
6a59680
resolve conflicts.
sayakpaul Mar 13, 2026
efc49a1
Update docs/source/cli-init.md
sayakpaul Mar 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions docs/source/_toctree.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,4 @@
title: kernels download
- local: cli-skills
title: kernels skills
- local: cli-create-and-upload-card
title: kernels create-and-upload-card
title: CLI Reference
15 changes: 15 additions & 0 deletions docs/source/builder/writing-kernels.md
Original file line number Diff line number Diff line change
Expand Up @@ -330,3 +330,18 @@ $ nix run .#ciTests.torch210-cxx11-cpu-x86_64-linux

When running the tests on a non-NixOS systems, make sure that
[the CUDA driver library can be found](https://danieldk.eu/Software/Nix/Nix-CUDA-on-non-NixOS-systems#solutions).

## Kernel docs

We provide a utility to generate a system card for a given kernel, utilizing
information from its `build.toml` and metadata. This system card provides a
reasonable starting point and is meant to be edited afterward by the kernel
developer.

The template card is generated as a part of [`kernels init`](../cli-init.md)
command and is serialized in the root directory of the kernel.

The card will be filled automatically by the builder when using the
`build-and-upload` or `build-and-copy` command. It will be serialized
to the `build` sub-directory inside the main kernel directory. It
will be uploaded as `README.md` to the Hub.
5 changes: 0 additions & 5 deletions docs/source/cli-create-and-upload-card.md

This file was deleted.

2 changes: 2 additions & 0 deletions docs/source/cli-init.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ This creates a new directory in the current working directory with the (normaliz
- Downloads a project template and replaces placeholders in file names, paths, and file contents
- Optionally restricts enabled backends (updates `build.toml` and removes unused backend folders)
- Initializes a Git repo and stages the files (`git init`, `git add .`)
- Initializes a templated system card for the kernel which is meant for the
kernel developer to further modify

## Examples

Expand Down
1 change: 1 addition & 0 deletions kernels/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ readme = "README.md"
requires-python = ">= 3.9"
dependencies = [
"huggingface_hub>=0.26.0,<2.0",
"Jinja2>=3.1.5",
"packaging>=20.0",
"pyyaml>=6",
"tomli>=2.0; python_version<'3.11'",
Expand Down
34 changes: 0 additions & 34 deletions kernels/src/kernels/card_template.md

This file was deleted.

91 changes: 39 additions & 52 deletions kernels/src/kernels/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,31 @@
import sys
from pathlib import Path

from huggingface_hub import ModelCard, ModelCardData

from kernels.cli.doc import generate_readme_for_kernel
from kernels.cli.init import parse_kernel_name, run_init
from kernels.cli.kernel_card_utils import (
DESCRIPTION,
KERNEL_CARD_TEMPLATE_PATH,
LIBRARY_NAME,
_build_kernel_card_vars,
_parse_repo_id,
_update_kernel_card_license,
)
from kernels.cli.skills import add_skill
from kernels.cli.upload import upload_kernels_dir
from kernels.cli.versions import print_kernel_versions
from kernels.compat import tomllib
from kernels.kernel_card_utils import (
_load_or_create_kernel_card,
_update_benchmark,
_update_kernel_card_available_funcs,
_update_kernel_card_backends,
_update_kernel_card_license,
_update_kernel_card_usage,
)
from kernels.lockfile import KernelLock, get_kernel_locks
from kernels.utils import (
KNOWN_BACKENDS,
install_kernel,
install_kernel_all_variants,
)

SYSTEM_CARD_PATH = "CARD.md"


def main():
parser = argparse.ArgumentParser(
Expand Down Expand Up @@ -247,36 +251,22 @@ def main():
)
init_parser.set_defaults(func=run_init)

repocard_parser = subparsers.add_parser(
"create-and-upload-card",
help="Create and optionally upload a kernel card.",
fill_card_parser = subparsers.add_parser(
"fill-card",
help="Fill a system card template based on the `build` information and save it.",
)
repocard_parser.add_argument(
fill_card_parser.add_argument(
"kernel_dir",
type=str,
help="Path to the kernels source.",
)
repocard_parser.add_argument(
"--card-path", type=str, required=True, help="Path to save the card to."
)
repocard_parser.add_argument(
fill_card_parser.add_argument(
"--description",
type=str,
default=None,
help="Description to introduce the kernel.",
)
repocard_parser.add_argument(
"--repo-id",
type=str,
default=None,
help="If specified it will be pushed to a repository on the Hub.",
)
repocard_parser.add_argument(
"--create-pr",
action="store_true",
help="If specified it will create a PR on the `repo_id`.",
)
repocard_parser.set_defaults(func=create_and_upload_card)
fill_card_parser.set_defaults(func=fill_kernel_card)

args = parser.parse_args()
args.func(args)
Expand Down Expand Up @@ -348,34 +338,31 @@ def upload_kernels(args):
)


def create_and_upload_card(args):
if not args.repo_id and args.create_pr:
raise ValueError("`create_pr` cannot be True when `repo_id` is None.")

def fill_kernel_card(args):
kernel_dir = Path(args.kernel_dir).resolve()
kernel_card = _load_or_create_kernel_card(
kernel_description=args.description, license="apache-2.0"
)
if not (kernel_dir / "build.toml").exists():
raise ValueError(
f"`build.toml` was not found in {str(kernel_dir)}. Cannot proceed."
)

updated_card = _update_kernel_card_usage(
kernel_card=kernel_card, local_path=kernel_dir, repo_id=args.repo_id
)
updated_card = _update_kernel_card_available_funcs(
kernel_card=kernel_card, local_path=kernel_dir
)
updated_card = _update_kernel_card_backends(
kernel_card=kernel_card, local_path=kernel_dir
)
updated_card = _update_benchmark(kernel_card=kernel_card, local_path=kernel_dir)
updated_card = _update_kernel_card_license(
kernel_card=kernel_card, local_path=kernel_dir
)
card_path = kernel_dir / "build" / SYSTEM_CARD_PATH

card_path = args.card_path
updated_card.save(card_path)
repo_id_from_build = _parse_repo_id(kernel_dir)
repo_id = repo_id_from_build or "{repo_id}"

if args.repo_id:
updated_card.push_to_hub(repo_id=args.repo_id, create_pr=args.create_pr)
dynamic_vars = _build_kernel_card_vars(kernel_dir, repo_id=repo_id)
description = (args.description or DESCRIPTION).format(repo_id=repo_id)

card_data = ModelCardData(library_name=LIBRARY_NAME)
updated_card = ModelCard.from_template(
card_data=card_data,
template_path=str(KERNEL_CARD_TEMPLATE_PATH),
kernel_description=description,
**dynamic_vars,
)
_update_kernel_card_license(updated_card, kernel_dir)
card_path.parent.mkdir(parents=True, exist_ok=True)
updated_card.save(card_path)
Comment thread
sayakpaul marked this conversation as resolved.


class _JSONEncoder(json.JSONEncoder):
Expand Down
38 changes: 38 additions & 0 deletions kernels/src/kernels/cli/card_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
{{ card_data }}
---

<!-- This model card has automatically been generated. You
should probably proofread and complete it, then remove this comment. -->

{{ kernel_description }}

## How to use

{{ usage_example }}

## Available functions

{{ available_functions }}

## Supported backends

{{ supported_backends }}
{% if cuda_capabilities %}

## CUDA Capabilities

{{ cuda_capabilities }}
{% endif %}

## Benchmarks

{{ benchmark_content }}

## Source code

{{ source_code }}

## Notes

{{ notes }}
11 changes: 11 additions & 0 deletions kernels/src/kernels/cli/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@
from huggingface_hub import snapshot_download
from huggingface_hub.utils import disable_progress_bars

from kernels.cli.kernel_card_utils import KERNEL_CARD_TEMPLATE_PATH
from kernels.utils import KNOWN_BACKENDS

SYSTEM_CARD_FILENAME = "CARD.md"

KERNEL_NAME_PATTERN = re.compile(r"^[a-z][-a-z0-9]*[a-z0-9]$")


Expand Down Expand Up @@ -98,6 +101,9 @@ def run_init(args: Namespace) -> None:

_remove_backend_dirs(target_dir, backends)

# Generate the card template
_initialize_card(target_dir)

# Initialize git repo (required for Nix flakes)
subprocess.run(["git", "init"], cwd=target_dir, check=True, capture_output=True)
subprocess.run(["git", "add", "."], cwd=target_dir, check=True, capture_output=True)
Expand All @@ -111,6 +117,11 @@ def run_init(args: Namespace) -> None:
print("uv run example.py")


def _initialize_card(target_dir: Path) -> None:
card_path = target_dir / SYSTEM_CARD_FILENAME
shutil.copy(KERNEL_CARD_TEMPLATE_PATH, card_path)


def _init_from_local_template(
template_dir: Path,
target_dir: Path,
Expand Down
Loading
Loading