chore: import upstream snapshot with attribution
Book-CI / test (macos-latest) (push) Has been cancelled
Book-CI / test (ubuntu-latest) (push) Has been cancelled
Book-CI / test (windows-latest) (push) Has been cancelled
Release Fake Tag / publish (push) Has been cancelled
Deploy / deploy (macos-latest) (push) Has been cancelled
Deploy / deploy (ubuntu-latest) (push) Has been cancelled
Deploy / deploy (windows-latest) (push) Has been cancelled
Release to PyPI / Build & publish sglang-kt (push) Has been cancelled
Release to PyPI / Build kt-kernel (Python 3.11) (push) Has been cancelled
Release to PyPI / Build kt-kernel (Python 3.12) (push) Has been cancelled
Release to PyPI / Publish kt-kernel to PyPI (push) Has been cancelled
Book-CI / test (macos-latest) (push) Has been cancelled
Book-CI / test (ubuntu-latest) (push) Has been cancelled
Book-CI / test (windows-latest) (push) Has been cancelled
Release Fake Tag / publish (push) Has been cancelled
Deploy / deploy (macos-latest) (push) Has been cancelled
Deploy / deploy (ubuntu-latest) (push) Has been cancelled
Deploy / deploy (windows-latest) (push) Has been cancelled
Release to PyPI / Build & publish sglang-kt (push) Has been cancelled
Release to PyPI / Build kt-kernel (Python 3.11) (push) Has been cancelled
Release to PyPI / Build kt-kernel (Python 3.12) (push) Has been cancelled
Release to PyPI / Publish kt-kernel to PyPI (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at [INSERT CONTACT METHOD]. All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at [https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0].
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder][Mozilla CoC].
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at [https://www.contributor-covenant.org/translations][translations].
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html
|
||||
[Mozilla CoC]: https://github.com/mozilla/diversity
|
||||
[FAQ]: https://www.contributor-covenant.org/faq
|
||||
[translations]: https://www.contributor-covenant.org/translations
|
||||
@@ -0,0 +1,139 @@
|
||||
## Before Commit!
|
||||
|
||||
Your commit message must follow Conventional Commits (https://www.conventionalcommits.org/) and your code should be formatted. The Git hooks will do most of the work automatically:
|
||||
|
||||
### Tool Requirements
|
||||
|
||||
You need a recent `clang-format` (>= 18). In a conda environment you can install:
|
||||
|
||||
```shell
|
||||
conda install -c conda-forge clang-format=18
|
||||
```
|
||||
|
||||
If you previously configured with an older version, remove the build directory and reconfigure:
|
||||
|
||||
```shell
|
||||
rm -rf kt-kernel/build
|
||||
```
|
||||
|
||||
Install `black` for Python formatting:
|
||||
|
||||
```shell
|
||||
conda install black
|
||||
```
|
||||
|
||||
### Install hook:
|
||||
```shell
|
||||
bash kt-kernel/scripts/install-git-hooks.sh
|
||||
#or just cmake the kt-kernel
|
||||
cmake -S kt-kernel -B kt-kernel/build
|
||||
```
|
||||
|
||||
There are manual commands if you need format.
|
||||
|
||||
```shell
|
||||
cmake -S kt-kernel -B kt-kernel/build
|
||||
cmake --build kt-kernel/build --target format
|
||||
```
|
||||
|
||||
## Developer Note
|
||||
|
||||
Formatting and commit message rules are enforced by Git hooks. After installing `clang-format` and `black`, just commit normally—the hooks will run formatting for you.
|
||||
|
||||
> [!NOTE]
|
||||
> If formatting modifies files, the commit is aborted after staging those changes. Review them and run `git commit` again. Repeat until no further formatting changes appear.
|
||||
|
||||
---
|
||||
|
||||
### Conventional Commit Regex (Reference)
|
||||
|
||||
The commit-msg hook enforces this pattern:
|
||||
|
||||
```text
|
||||
regex='^\[(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert|wip)\](\([^\)]+\))?(!)?: .+'
|
||||
```
|
||||
|
||||
Meaning (English):
|
||||
* `[type]` required — one of feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert|wip
|
||||
* Optional scope: `(scope)` — any chars except `)`
|
||||
* Optional breaking change marker: `!` right after type or scope
|
||||
* Separator: `: ` (colon + space)
|
||||
* Subject: free text (at least one character)
|
||||
|
||||
Examples:
|
||||
```text
|
||||
[feat]: add adaptive batching
|
||||
[fix(parser)]: handle empty token list
|
||||
[docs]!: update API section for breaking rename
|
||||
```
|
||||
|
||||
You can bypass locally (not recommended) with:
|
||||
```shell
|
||||
git commit --no-verify
|
||||
```
|
||||
## 提交前提醒
|
||||
|
||||
提交信息必须满足 Conventional Commits 规范 (https://www.conventionalcommits.org/),代码需要符合格式要求。Git 钩子已经集成了大部分工作:
|
||||
### 软件要求
|
||||
|
||||
需要较新的 `clang-format` (>= 18),在 conda 环境中安装:
|
||||
|
||||
```shell
|
||||
conda install -c conda-forge clang-format=18
|
||||
```
|
||||
|
||||
如果之前用老版本配置过,请删除构建目录重新配置:
|
||||
|
||||
```shell
|
||||
rm -rf kt-kernel/build
|
||||
```
|
||||
|
||||
安装 `black` 以进行 Python 文件格式化:
|
||||
|
||||
```shell
|
||||
conda install black
|
||||
```
|
||||
### 安装钩子
|
||||
```shell
|
||||
bash kt-kernel/scripts/install-git-hooks.sh
|
||||
#or just cmake the kt-kernel
|
||||
cmake -S kt-kernel -B kt-kernel/build
|
||||
```
|
||||
如果你需要手动格式化:
|
||||
```shell
|
||||
cmake -S kt-kernel -B kt-kernel/build
|
||||
cmake --build kt-kernel/build --target format
|
||||
```
|
||||
|
||||
## 开发者说明
|
||||
|
||||
本仓库通过 Git hooks 自动执行代码格式化与提交信息规范检查。只需安装好 `clang-format` 与 `black` 后正常执行提交即可,钩子会自动格式化。
|
||||
|
||||
> [!NOTE]
|
||||
> 如果格式化修改了文件,钩子会终止提交并已暂存这些改动。请查看修改后再次执行 `git commit`,重复直到没有新的格式化变更。
|
||||
|
||||
### 提交信息正则(参考)
|
||||
|
||||
钩子使用如下正则检查提交信息:
|
||||
```text
|
||||
regex='^\[(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert|wip)\](\([^\)]+\))?(!)?: .+'
|
||||
```
|
||||
含义:
|
||||
* `[type]` 必填:feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert|wip
|
||||
* 作用域可选:`(scope)`,不能包含右括号
|
||||
* 可选的破坏性标记:`!`
|
||||
* 分隔符:冒号+空格 `: `
|
||||
* 描述:至少一个字符
|
||||
|
||||
示例:
|
||||
```text
|
||||
[feat]: 增加自适应 batch 功能
|
||||
[fix(tokenizer)]: 修复空 token 列表处理
|
||||
[docs]!: 更新接口文档(存在破坏性修改)
|
||||
```
|
||||
|
||||
跳过钩子(不推荐,仅紧急时):
|
||||
```shell
|
||||
git commit --no-verify
|
||||
```
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
name: "\U0001F41B Bug / Help"
|
||||
description: Create a report to help us improve the ktransformers project
|
||||
labels: ["pending"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Issues included in **[FAQs](https://github.com/kvcache-ai/ktransformers/issues/1608)** or those with **insufficient** information may be closed without a response.
|
||||
已经包含在 **[常见问题](https://github.com/kvcache-ai/ktransformers/issues/1608)** 内或提供信息**不完整**的 issues 可能不会被回复。
|
||||
|
||||
- type: checkboxes
|
||||
id: reminder
|
||||
attributes:
|
||||
label: Reminder
|
||||
description: |
|
||||
Please ensure you have read the above rules carefully and searched the existing issues (including FAQs).
|
||||
请确保您已经认真阅读了上述规则并且搜索过现有的 issues(包括常见问题)。
|
||||
|
||||
options:
|
||||
- label: I have read the above rules and searched the existing issues.
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: system-info
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: System Info
|
||||
description: |
|
||||
Please share your system info with us. You can run the command **lscpu**, ** nvidia-smi ** etc. and copy-paste its output below.
|
||||
请提供您的系统信息。您可以在命令行运行 **lscpu**, **nvidia-smi** 等命令,并将其输出复制到该文本框中。
|
||||
|
||||
placeholder: ktransformers version,sglang version, platform, python version, cpu info, GPU/NPU info ...
|
||||
|
||||
- type: textarea
|
||||
id: reproduction
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: Reproduction
|
||||
description: |
|
||||
Please provide entry arguments, error messages and stack traces that reproduces the problem.
|
||||
请提供入口参数,错误日志以及异常堆栈以便于我们复现问题。
|
||||
|
||||
value: |
|
||||
```text
|
||||
Put your message here.
|
||||
```
|
||||
|
||||
- type: textarea
|
||||
id: others
|
||||
validations:
|
||||
required: false
|
||||
attributes:
|
||||
label: Others
|
||||
@@ -0,0 +1,41 @@
|
||||
name: "\U0001F680 Feature request"
|
||||
description: Submit a request for a new feature
|
||||
labels: ["enhancement", "pending"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please do not create issues that are not related to new features under this category.
|
||||
请勿在此分类下创建和新特性无关的 issues。
|
||||
|
||||
- type: checkboxes
|
||||
id: reminder
|
||||
attributes:
|
||||
label: Reminder
|
||||
description: |
|
||||
Please ensure you have read the above rules carefully and searched the existing issues.
|
||||
请确保您已经认真阅读了上述规则并且搜索过现有的 issues。
|
||||
|
||||
options:
|
||||
- label: I have read the above rules and searched the existing issues.
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: description
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: Description
|
||||
description: |
|
||||
A clear and concise description of the feature proposal.
|
||||
请详细描述您希望加入的新功能特性。
|
||||
|
||||
- type: textarea
|
||||
id: contribution
|
||||
validations:
|
||||
required: false
|
||||
attributes:
|
||||
label: Pull Request
|
||||
description: |
|
||||
Have you already created the relevant PR and submitted the code?
|
||||
您是否已经创建了相关 PR 并提交了代码?
|
||||
@@ -0,0 +1,5 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: 📚 FAQs | 常见问题
|
||||
url: https://github.com/kvcache-ai/ktransformers/issues/1608
|
||||
about: Reading in advance is recommended | 建议提前阅读
|
||||
@@ -0,0 +1,8 @@
|
||||
# What does this PR do?
|
||||
|
||||
Fixes # (issue)
|
||||
|
||||
## Before submitting
|
||||
|
||||
- [ ] Did you read the [contributor guideline](https://github.com/kvcache-ai/ktransformers/blob/main/.github/CONTRIBUTING.md)?
|
||||
- [ ] Did you write any new necessary tests?
|
||||
@@ -0,0 +1,7 @@
|
||||
# Reporting Security Issues
|
||||
|
||||
To report a security issue, please use the GitHub Security Advisory ["Report a Vulnerability"](https://github.com/kvcache-ai/ktransformers/security/advisories/new) tab.
|
||||
|
||||
We will send a response indicating the next steps in handling your report. After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.
|
||||
|
||||
Report security bugs in third-party modules to the person or team maintaining the module.
|
||||
@@ -0,0 +1,32 @@
|
||||
name: Book-CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
# - server_support
|
||||
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
# - server_support
|
||||
jobs:
|
||||
test:
|
||||
name: test
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Rust
|
||||
run: |
|
||||
rustup set profile minimal
|
||||
rustup toolchain install stable
|
||||
rustup default stable
|
||||
- name: Setup mdBook
|
||||
uses: peaceiris/actions-mdbook@v2
|
||||
with:
|
||||
mdbook-version: "latest"
|
||||
# - name: Run tests
|
||||
# run: mdbook test
|
||||
@@ -0,0 +1,49 @@
|
||||
name: Deploy
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
# - server_support
|
||||
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
# - server_support
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Rust
|
||||
run: |
|
||||
rustup set profile minimal
|
||||
rustup toolchain install stable
|
||||
rustup default stable
|
||||
- name: Setup mdBook
|
||||
uses: peaceiris/actions-mdbook@v2
|
||||
with:
|
||||
mdbook-version: "latest"
|
||||
- run: mdbook build
|
||||
# - name: Copy Assets
|
||||
# run: |
|
||||
# chmod +x ci/copy-assets.sh
|
||||
# ci/copy-assets.sh ${{ matrix.os }}
|
||||
- name: Deploy
|
||||
uses: peaceiris/actions-gh-pages@v3
|
||||
# or || github.ref == 'refs/heads/server_support'
|
||||
if: ${{ github.ref == 'refs/heads/main' }}
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_dir: ./book
|
||||
@@ -0,0 +1,142 @@
|
||||
name: DockerHub CI
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
push_to_dockerhub:
|
||||
description: 'Push image to DockerHub? (true/false)'
|
||||
required: true
|
||||
default: 'false'
|
||||
type: boolean
|
||||
cuda_version:
|
||||
description: 'CUDA version (e.g., 12.8.1)'
|
||||
required: false
|
||||
default: '12.8.1'
|
||||
type: string
|
||||
push_simplified_tag:
|
||||
description: 'Also push simplified tag? (true/false)'
|
||||
required: false
|
||||
default: 'true'
|
||||
type: boolean
|
||||
ubuntu_mirror:
|
||||
description: 'Use Tsinghua Ubuntu mirror? (0/1)'
|
||||
required: false
|
||||
default: '0'
|
||||
type: string
|
||||
|
||||
# push:
|
||||
# branches:
|
||||
# - main
|
||||
env:
|
||||
DOCKERHUB_REPO: ${{ secrets.DOCKERHUB_USERNAME }}/ktransformers
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Run tests
|
||||
run: |
|
||||
if [ -f docker-compose.test.yml ]; then
|
||||
docker-compose --file docker-compose.test.yml build
|
||||
docker-compose --file docker-compose.test.yml run sut
|
||||
else
|
||||
docker build . --file docker/Dockerfile
|
||||
fi
|
||||
|
||||
build-and-push:
|
||||
needs: test
|
||||
name: Build and Push Multi-Variant Docker Image
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Move Docker data directory
|
||||
run: |
|
||||
sudo systemctl stop docker
|
||||
sudo mkdir -p /mnt/docker
|
||||
sudo rsync -avz /var/lib/docker/ /mnt/docker
|
||||
sudo rm -rf /var/lib/docker
|
||||
sudo ln -s /mnt/docker /var/lib/docker
|
||||
sudo systemctl start docker
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Determine build parameters
|
||||
id: params
|
||||
run: |
|
||||
# Determine if we should push
|
||||
if [ "${{ github.event_name }}" = "release" ]; then
|
||||
echo "should_push=true" >> $GITHUB_OUTPUT
|
||||
echo "push_simplified=true" >> $GITHUB_OUTPUT
|
||||
elif [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||||
echo "should_push=${{ inputs.push_to_dockerhub }}" >> $GITHUB_OUTPUT
|
||||
echo "push_simplified=${{ inputs.push_simplified_tag }}" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "should_push=false" >> $GITHUB_OUTPUT
|
||||
echo "push_simplified=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
# Determine CUDA version
|
||||
if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ -n "${{ inputs.cuda_version }}" ]; then
|
||||
echo "cuda_version=${{ inputs.cuda_version }}" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "cuda_version=12.8.1" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
# Determine Ubuntu mirror setting
|
||||
if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ -n "${{ inputs.ubuntu_mirror }}" ]; then
|
||||
echo "ubuntu_mirror=${{ inputs.ubuntu_mirror }}" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "ubuntu_mirror=0" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Build and push Docker image
|
||||
run: |
|
||||
cd docker
|
||||
|
||||
# Build command arguments
|
||||
BUILD_ARGS=(
|
||||
--cuda-version "${{ steps.params.outputs.cuda_version }}"
|
||||
--ubuntu-mirror "${{ steps.params.outputs.ubuntu_mirror }}"
|
||||
--repository "${{ env.DOCKERHUB_REPO }}"
|
||||
)
|
||||
|
||||
# Add simplified tag option if enabled
|
||||
if [ "${{ steps.params.outputs.push_simplified }}" = "true" ]; then
|
||||
BUILD_ARGS+=(--also-push-simplified)
|
||||
fi
|
||||
|
||||
# Add HTTP proxy if available
|
||||
if [ -n "${{ secrets.HTTP_PROXY }}" ]; then
|
||||
BUILD_ARGS+=(--http-proxy "${{ secrets.HTTP_PROXY }}")
|
||||
fi
|
||||
|
||||
# Add HTTPS proxy if available
|
||||
if [ -n "${{ secrets.HTTPS_PROXY }}" ]; then
|
||||
BUILD_ARGS+=(--https-proxy "${{ secrets.HTTPS_PROXY }}")
|
||||
fi
|
||||
|
||||
# Dry run if not pushing
|
||||
if [ "${{ steps.params.outputs.should_push }}" != "true" ]; then
|
||||
BUILD_ARGS+=(--dry-run)
|
||||
fi
|
||||
|
||||
# Execute build script
|
||||
./push-to-dockerhub.sh "${BUILD_ARGS[@]}"
|
||||
|
||||
- name: Display image information
|
||||
if: steps.params.outputs.should_push == 'true'
|
||||
run: |
|
||||
echo "::notice title=Docker Image::Image pushed successfully to ${{ env.DOCKERHUB_REPO }}"
|
||||
echo "Pull command: docker pull ${{ env.DOCKERHUB_REPO }}:v\$(VERSION)-cu\$(CUDA_SHORT)"
|
||||
@@ -0,0 +1,104 @@
|
||||
name: PR KT-Kernel Test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- develop
|
||||
types: [synchronize, labeled]
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: pr-kt-kernel-test-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
# =============================================== check changes ====================================================
|
||||
check-changes:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
kt_kernel: ${{ steps.filter.outputs.kt_kernel }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Fail if the PR does not have the 'run-ci' label
|
||||
if: github.event_name == 'pull_request' && !contains(github.event.pull_request.labels.*.name, 'run-ci')
|
||||
run: |
|
||||
echo "This pull request does not have the 'run-ci' label. Failing the workflow."
|
||||
exit 1
|
||||
|
||||
- name: Fail if the PR is a draft
|
||||
if: github.event_name == 'pull_request' && github.event.pull_request.draft == true
|
||||
run: |
|
||||
echo "This pull request is a draft. Failing the workflow."
|
||||
exit 1
|
||||
|
||||
- name: Detect file changes
|
||||
id: filter
|
||||
uses: dorny/paths-filter@v3
|
||||
with:
|
||||
filters: |
|
||||
kt_kernel:
|
||||
- "kt-kernel/**"
|
||||
- ".github/workflows/kt-kernel-tests.yml"
|
||||
|
||||
# =============================================== KT-Kernel tests ====================================================
|
||||
per-commit-kt-kernel-cpu:
|
||||
needs: [check-changes]
|
||||
if: always() && !failure() && !cancelled() &&
|
||||
(needs.check-changes.outputs.kt_kernel == 'true' || github.event_name == 'workflow_dispatch')
|
||||
runs-on: kt-cpu
|
||||
continue-on-error: false
|
||||
steps:
|
||||
- name: Cleanup
|
||||
run: |
|
||||
sudo rm -rf $GITHUB_WORKSPACE/* || true
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install KT-Kernel
|
||||
run: |
|
||||
cd kt-kernel
|
||||
bash install.sh build
|
||||
|
||||
- name: Run KT-Kernel CPU tests
|
||||
timeout-minutes: 60
|
||||
run: |
|
||||
cd kt-kernel/test
|
||||
python3 run_suite.py --hw cpu --suite default
|
||||
|
||||
# =============================================== finish ====================================================
|
||||
pr-test-kt-kernel-finish:
|
||||
needs: [check-changes, per-commit-kt-kernel-cpu]
|
||||
if: always()
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check all dependent job statuses
|
||||
run: |
|
||||
# Convert the 'needs' context to a JSON string
|
||||
json_needs='${{ toJson(needs) }}'
|
||||
|
||||
# Get a list of all job names from the JSON keys
|
||||
job_names=$(echo "$json_needs" | jq -r 'keys_unsorted[]')
|
||||
|
||||
for job in $job_names; do
|
||||
# For each job, extract its result
|
||||
result=$(echo "$json_needs" | jq -r --arg j "$job" '.[$j].result')
|
||||
|
||||
# Print the job name and its result
|
||||
echo "$job: $result"
|
||||
|
||||
# Check for failure or cancellation and exit if found
|
||||
if [[ "$result" == "failure" || "$result" == "cancelled" ]]; then
|
||||
echo "The above jobs failed."
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# If the loop completes, all jobs were successful
|
||||
echo "All jobs completed successfully"
|
||||
exit 0
|
||||
@@ -0,0 +1,41 @@
|
||||
name: Release Fake Tag
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "version.py"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
if: github.repository == 'kvcache-ai/ktransformers'
|
||||
runs-on: ubuntu-latest
|
||||
environment: 'prod'
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Get version
|
||||
id: get_version
|
||||
run: |
|
||||
version=$(cat version.py | grep '__version__' | cut -d'"' -f2)
|
||||
echo "TAG=v$version" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Create and push tag
|
||||
run: |
|
||||
TAG=${{ steps.get_version.outputs.TAG }}
|
||||
git config user.name "ktransformers-bot"
|
||||
git config user.email "ktransformers-bot@users.noreply.github.com"
|
||||
if git ls-remote --tags --exit-code origin "refs/tags/${TAG}" > /dev/null 2>&1; then
|
||||
echo "Tag ${TAG} already exists on origin, skipping."
|
||||
exit 0
|
||||
fi
|
||||
git tag "${TAG}"
|
||||
git push origin "${TAG}"
|
||||
@@ -0,0 +1,283 @@
|
||||
name: Release to PyPI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "version.py"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
test_pypi:
|
||||
description: 'Publish to TestPyPI instead of PyPI (for testing)'
|
||||
required: false
|
||||
default: 'false'
|
||||
type: choice
|
||||
options:
|
||||
- 'true'
|
||||
- 'false'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
# ── sglang-kt (must be on PyPI before users can pip install kt-kernel) ──
|
||||
build-and-publish-sglang-kt:
|
||||
name: Build & publish sglang-kt
|
||||
runs-on: [self-hosted, linux, x64]
|
||||
if: github.repository == 'kvcache-ai/ktransformers' && github.ref == 'refs/heads/main'
|
||||
environment: prod
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.12'
|
||||
|
||||
- name: Install build tools
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install build wheel setuptools twine
|
||||
|
||||
- name: Build sglang-kt wheel
|
||||
working-directory: third_party/sglang/python
|
||||
run: |
|
||||
KT_VERSION=$(python3 -c "exec(open('${{ github.workspace }}/version.py').read()); print(__version__)")
|
||||
export SGLANG_KT_VERSION="$KT_VERSION"
|
||||
echo "Building sglang-kt v${KT_VERSION} wheel..."
|
||||
python -m build --wheel -v
|
||||
ls dist/ | grep -q "sglang_kt" || (echo "ERROR: Wheel name does not contain sglang_kt" && exit 1)
|
||||
|
||||
- name: Publish sglang-kt to PyPI
|
||||
if: github.event.inputs.test_pypi != 'true'
|
||||
env:
|
||||
TWINE_USERNAME: __token__
|
||||
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
|
||||
run: |
|
||||
python -m twine upload --skip-existing --verbose third_party/sglang/python/dist/*.whl
|
||||
|
||||
- name: Publish sglang-kt to TestPyPI (if requested)
|
||||
if: github.event.inputs.test_pypi == 'true'
|
||||
env:
|
||||
TWINE_USERNAME: __token__
|
||||
TWINE_PASSWORD: ${{ secrets.TEST_PYPI_API_TOKEN }}
|
||||
run: |
|
||||
python -m twine upload --repository testpypi --skip-existing --verbose third_party/sglang/python/dist/*.whl
|
||||
|
||||
# ── kt-kernel ──
|
||||
build-kt-kernel:
|
||||
name: Build kt-kernel (Python ${{ matrix.python-version }})
|
||||
runs-on: [self-hosted, linux, x64, gpu]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ['3.11', '3.12']
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Verify CUDA availability
|
||||
run: |
|
||||
nvidia-smi || (echo "ERROR: GPU not available" && exit 1)
|
||||
nvcc --version || (echo "ERROR: CUDA toolkit not found" && exit 1)
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
# System packages (cmake/libhwloc-dev/pkg-config/libnuma-dev) are expected to be
|
||||
# preinstalled on self-hosted runners. Skip apt-get to avoid sudo dependency.
|
||||
for pkg in cmake pkg-config; do command -v $pkg >/dev/null || { echo "ERROR: $pkg missing on runner"; exit 1; }; done
|
||||
python -m pip install --upgrade pip
|
||||
pip install build wheel setuptools
|
||||
pip install torch --index-url https://download.pytorch.org/whl/cu128
|
||||
|
||||
- name: Build kt-kernel wheel
|
||||
working-directory: kt-kernel
|
||||
env:
|
||||
CPUINFER_BUILD_ALL_VARIANTS: '1'
|
||||
CPUINFER_ENABLE_CPPTRACE: '0'
|
||||
CPUINFER_USE_CUDA: '1'
|
||||
CPUINFER_CUDA_ARCHS: '80;86;89;90;120'
|
||||
CPUINFER_CUDA_STATIC_RUNTIME: '1'
|
||||
CPUINFER_BUILD_TYPE: 'Release'
|
||||
CPUINFER_PARALLEL: '4'
|
||||
CPUINFER_FORCE_REBUILD: '1'
|
||||
CUDA_HOME: '/usr/local/cuda-12.8'
|
||||
run: |
|
||||
echo "Building kt-kernel with:"
|
||||
echo " - CUDA support (SM 80, 86, 89, 90, 120)"
|
||||
echo " - CPU multi-variant (AMX, AVX512, AVX2)"
|
||||
python -m build --wheel -v
|
||||
|
||||
- name: Verify wheel
|
||||
working-directory: kt-kernel
|
||||
run: |
|
||||
echo "Generated wheel:"
|
||||
ls -lh dist/
|
||||
|
||||
# Install and test
|
||||
pip install dist/*.whl
|
||||
python -c "import kt_kernel; print(f'✓ Version: {kt_kernel.__version__}')"
|
||||
python -c "import kt_kernel; print(f'✓ CPU variant: {kt_kernel.__cpu_variant__}')"
|
||||
|
||||
# Verify CUDA support
|
||||
python -c "
|
||||
from kt_kernel import kt_kernel_ext
|
||||
cpu_infer = kt_kernel_ext.CPUInfer(4)
|
||||
methods = dir(cpu_infer)
|
||||
has_cuda = 'submit_with_cuda_stream' in methods
|
||||
print(f'✓ CUDA support: {has_cuda}')
|
||||
"
|
||||
|
||||
# Verify CPU multi-variant support
|
||||
echo "Checking CPU variants in wheel..."
|
||||
python -m zipfile -l dist/*.whl | grep "_kt_kernel_ext_" || echo "Warning: No variant .so files found"
|
||||
python -m zipfile -l dist/*.whl | grep "_kt_kernel_ext_amx.cpython" && echo "✓ AMX variant found" || echo "Note: AMX variant missing"
|
||||
python -m zipfile -l dist/*.whl | grep "_kt_kernel_ext_avx512" && echo "✓ AVX512 variants found" || echo "Note: AVX512 variants missing"
|
||||
python -m zipfile -l dist/*.whl | grep "_kt_kernel_ext_avx2.cpython" && echo "✓ AVX2 variant found" || echo "Note: AVX2 variant missing"
|
||||
|
||||
# Verify static linking (should NOT depend on libcudart.so).
|
||||
# Use $RUNNER_TEMP (honors TMPDIR redirect to /mnt) — /tmp is the
|
||||
# system disk on self-hosted runners and can be tight.
|
||||
CHECK_DIR="${RUNNER_TEMP:-/tmp}/check"
|
||||
rm -rf "$CHECK_DIR"
|
||||
unzip -q dist/*.whl -d "$CHECK_DIR"
|
||||
if ldd "$CHECK_DIR"/kt_kernel/*.so 2>/dev/null | grep -q "libcudart.so"; then
|
||||
echo "ERROR: Dynamic cudart found, should be statically linked"
|
||||
exit 1
|
||||
else
|
||||
echo "✓ CUDA runtime statically linked"
|
||||
fi
|
||||
|
||||
- name: Repair wheel for manylinux
|
||||
working-directory: kt-kernel
|
||||
run: |
|
||||
pip install auditwheel patchelf
|
||||
mkdir -p wheelhouse
|
||||
for wheel in dist/*.whl; do
|
||||
auditwheel repair "$wheel" --plat manylinux_2_35_x86_64 --exclude libcuda.so.1 -w wheelhouse/
|
||||
done
|
||||
rm -f dist/*.whl && cp wheelhouse/*.whl dist/
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: kt-kernel-wheels-py${{ matrix.python-version }}
|
||||
path: kt-kernel/dist/*.whl
|
||||
retention-days: 7
|
||||
|
||||
publish-pypi:
|
||||
name: Publish kt-kernel to PyPI
|
||||
needs: [build-and-publish-sglang-kt, build-kt-kernel]
|
||||
runs-on: [self-hosted, linux, x64]
|
||||
if: github.repository == 'kvcache-ai/ktransformers' && github.ref == 'refs/heads/main'
|
||||
environment: prod
|
||||
permissions:
|
||||
id-token: write # For trusted publishing (OIDC)
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Download all wheel artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: artifacts/
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.12'
|
||||
|
||||
- name: Organize wheels into dist/
|
||||
run: |
|
||||
mkdir -p dist/
|
||||
find artifacts/ -name "*.whl" -exec cp {} dist/ \;
|
||||
echo "Wheels to publish:"
|
||||
ls -lh dist/
|
||||
|
||||
- name: Get version from wheel
|
||||
id: get_version
|
||||
run: |
|
||||
# Extract version from first wheel filename
|
||||
wheel_name=$(ls dist/*.whl | head -1 | xargs basename)
|
||||
# Extract version (format: kt_kernel-X.Y.Z-...)
|
||||
version=$(echo "$wheel_name" | sed 's/kt_kernel-\([0-9.]*\)-.*/\1/')
|
||||
echo "VERSION=$version" >> $GITHUB_OUTPUT
|
||||
echo "Publishing version: $version"
|
||||
|
||||
- name: Install twine
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install twine
|
||||
|
||||
- name: Publish to TestPyPI (if requested)
|
||||
if: github.event.inputs.test_pypi == 'true'
|
||||
env:
|
||||
TWINE_USERNAME: __token__
|
||||
TWINE_PASSWORD: ${{ secrets.TEST_PYPI_API_TOKEN }}
|
||||
run: |
|
||||
python -m twine upload \
|
||||
--repository testpypi \
|
||||
--skip-existing \
|
||||
--verbose \
|
||||
dist/*.whl
|
||||
|
||||
- name: Publish to PyPI
|
||||
if: github.event.inputs.test_pypi != 'true'
|
||||
env:
|
||||
TWINE_USERNAME: __token__
|
||||
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
|
||||
run: |
|
||||
python -m twine upload \
|
||||
--skip-existing \
|
||||
--verbose \
|
||||
dist/*.whl
|
||||
|
||||
- name: Create release summary
|
||||
run: |
|
||||
echo "## 🎉 kt-kernel v${{ steps.get_version.outputs.VERSION }} Published to PyPI" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "### Installation" >> $GITHUB_STEP_SUMMARY
|
||||
echo '```bash' >> $GITHUB_STEP_SUMMARY
|
||||
echo "pip install kt-kernel==${{ steps.get_version.outputs.VERSION }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "### Published Wheels" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Total: $(ls -1 dist/*.whl | wc -l) wheels (Python 3.10, 3.11, 3.12)" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "### Features" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**CPU Multi-Variant Support:**" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- ✅ AMX (Intel Sapphire Rapids+, 2023)" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- ✅ AVX512 Base/VNNI/VBMI/BF16 (Intel Skylake-X/Ice Lake/Cascade Lake, 2017+)" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- ✅ AVX2 (Maximum compatibility, 2013+)" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- 🔧 Runtime CPU detection: Automatically selects optimal variant" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**CUDA Support:**" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- ✅ SM 80 (Ampere: A100, RTX 3000 series)" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- ✅ SM 86 (Ampere: RTX 3060-3090)" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- ✅ SM 89 (Ada Lovelace: RTX 4000 series)" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- ✅ SM 90 (Hopper: H100)" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- 🔧 Static CUDA runtime: Compatible with CUDA 11.8+ and 12.x drivers" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- 🔧 Works on CPU-only systems (CUDA features disabled gracefully)" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Requirements:**" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Python 3.10, 3.11, or 3.12" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Linux x86-64 (manylinux_2_17 compatible)" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- For CUDA features: NVIDIA driver with CUDA 11.8+ or 12.x support" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "PyPI link: https://pypi.org/project/kt-kernel/${{ steps.get_version.outputs.VERSION }}/" >> $GITHUB_STEP_SUMMARY
|
||||
@@ -0,0 +1,129 @@
|
||||
name: Release sglang-kt to PyPI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "third_party/sglang"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
test_pypi:
|
||||
description: 'Publish to TestPyPI instead of PyPI (for testing)'
|
||||
required: false
|
||||
default: 'false'
|
||||
type: choice
|
||||
options:
|
||||
- 'true'
|
||||
- 'false'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build-sglang-kt:
|
||||
name: Build sglang-kt wheel
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.12'
|
||||
|
||||
- name: Install build tools
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install build wheel setuptools
|
||||
|
||||
- name: Build sglang-kt wheel
|
||||
working-directory: third_party/sglang/python
|
||||
run: |
|
||||
# Read version from ktransformers version.py
|
||||
KT_VERSION=$(python3 -c "exec(open('${{ github.workspace }}/version.py').read()); print(__version__)")
|
||||
export SGLANG_KT_VERSION="$KT_VERSION"
|
||||
echo "Building sglang-kt v${KT_VERSION} wheel..."
|
||||
python -m build --wheel -v
|
||||
|
||||
- name: Verify wheel
|
||||
working-directory: third_party/sglang/python
|
||||
run: |
|
||||
echo "Generated wheel:"
|
||||
ls -lh dist/
|
||||
# Verify the wheel has the correct package name
|
||||
ls dist/ | grep -q "sglang_kt" || (echo "ERROR: Wheel name does not contain sglang_kt" && exit 1)
|
||||
echo "Wheel name verified."
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: sglang-kt-wheel
|
||||
path: third_party/sglang/python/dist/*.whl
|
||||
retention-days: 7
|
||||
|
||||
publish-pypi:
|
||||
name: Publish sglang-kt to PyPI
|
||||
needs: [build-sglang-kt]
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'kvcache-ai/ktransformers' && github.ref == 'refs/heads/main'
|
||||
environment: prod
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Download wheel artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: sglang-kt-wheel
|
||||
path: dist/
|
||||
|
||||
- name: Display wheels
|
||||
run: |
|
||||
echo "Wheels to publish:"
|
||||
ls -lh dist/
|
||||
|
||||
- name: Install twine
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install twine
|
||||
|
||||
- name: Publish to TestPyPI (if requested)
|
||||
if: github.event.inputs.test_pypi == 'true'
|
||||
env:
|
||||
TWINE_USERNAME: __token__
|
||||
TWINE_PASSWORD: ${{ secrets.TEST_PYPI_API_TOKEN }}
|
||||
run: |
|
||||
python -m twine upload \
|
||||
--repository testpypi \
|
||||
--skip-existing \
|
||||
--verbose \
|
||||
dist/*.whl
|
||||
|
||||
- name: Publish to PyPI
|
||||
if: github.event.inputs.test_pypi != 'true'
|
||||
env:
|
||||
TWINE_USERNAME: __token__
|
||||
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
|
||||
run: |
|
||||
python -m twine upload \
|
||||
--skip-existing \
|
||||
--verbose \
|
||||
dist/*.whl
|
||||
|
||||
- name: Create release summary
|
||||
run: |
|
||||
echo "## sglang-kt Published to PyPI" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "### Installation" >> $GITHUB_STEP_SUMMARY
|
||||
echo '```bash' >> $GITHUB_STEP_SUMMARY
|
||||
echo "pip install sglang-kt" >> $GITHUB_STEP_SUMMARY
|
||||
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "This is the kvcache-ai fork of SGLang with kt-kernel support." >> $GITHUB_STEP_SUMMARY
|
||||
echo "PyPI link: https://pypi.org/project/sglang-kt/" >> $GITHUB_STEP_SUMMARY
|
||||
@@ -0,0 +1,81 @@
|
||||
name: Sync sglang submodule
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# Run daily at 08:00 UTC
|
||||
- cron: "0 8 * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
sync:
|
||||
name: Check for sglang-kt updates
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Update sglang submodule to latest main
|
||||
id: update
|
||||
run: |
|
||||
OLD_SHA=$(git -C third_party/sglang rev-parse HEAD)
|
||||
git submodule update --remote third_party/sglang
|
||||
NEW_SHA=$(git -C third_party/sglang rev-parse HEAD)
|
||||
|
||||
echo "old_sha=$OLD_SHA" >> "$GITHUB_OUTPUT"
|
||||
echo "new_sha=$NEW_SHA" >> "$GITHUB_OUTPUT"
|
||||
|
||||
if [ "$OLD_SHA" = "$NEW_SHA" ]; then
|
||||
echo "changed=false" >> "$GITHUB_OUTPUT"
|
||||
echo "sglang submodule is already up to date ($OLD_SHA)"
|
||||
else
|
||||
echo "changed=true" >> "$GITHUB_OUTPUT"
|
||||
|
||||
# Collect commit log between old and new
|
||||
COMMITS=$(git -C third_party/sglang log --oneline "$OLD_SHA..$NEW_SHA" | head -20)
|
||||
echo "commits<<EOF" >> "$GITHUB_OUTPUT"
|
||||
echo "$COMMITS" >> "$GITHUB_OUTPUT"
|
||||
echo "EOF" >> "$GITHUB_OUTPUT"
|
||||
|
||||
# sglang-kt version = ktransformers version (from version.py)
|
||||
VERSION=$(python3 -c "exec(open('version.py').read()); print(__version__)" 2>/dev/null || echo "unknown")
|
||||
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
||||
|
||||
echo "sglang submodule updated: $OLD_SHA -> $NEW_SHA (v$VERSION)"
|
||||
fi
|
||||
|
||||
- name: Create pull request
|
||||
if: steps.update.outputs.changed == 'true'
|
||||
uses: peter-evans/create-pull-request@v6
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
commit-message: |
|
||||
[build]: sync sglang submodule to ${{ steps.update.outputs.new_sha }}
|
||||
branch: auto/sync-sglang
|
||||
delete-branch: true
|
||||
title: "[build] Sync sglang-kt submodule (v${{ steps.update.outputs.version }})"
|
||||
body: |
|
||||
Automated sync of `third_party/sglang` submodule to latest `main`.
|
||||
|
||||
**Old ref:** `${{ steps.update.outputs.old_sha }}`
|
||||
**New ref:** `${{ steps.update.outputs.new_sha }}`
|
||||
**sglang-kt version:** `${{ steps.update.outputs.version }}`
|
||||
|
||||
### Commits included
|
||||
```
|
||||
${{ steps.update.outputs.commits }}
|
||||
```
|
||||
|
||||
---
|
||||
*This PR was created automatically by the [sync-sglang-submodule](${{ github.server_url }}/${{ github.repository }}/actions/workflows/sync-sglang-submodule.yml) workflow.*
|
||||
labels: |
|
||||
dependencies
|
||||
automated
|
||||
Reference in New Issue
Block a user