기여 가이드
기여 가이드 (Ascend NPU)
SGLang에 오신 걸 환영해요! 기여에 관심을 가져 주셔서 감사해요. 이 가이드는 환경 설정, 테스트 실행, 문서 빌드, Pull Request(PR) 열기까지의 과정을 간결하게 정리해요. 작은 버그 수리든 큰 기능 개발이든, 이 단계들을 따라가면 매끄럽게 기여할 수 있어요.
소스에서 SGLang 설치하기
환경 준비
기여하기 전에 환경이 올바르게 설정됐는지 확인하세요. 설치 가이드의 단계를 따라 필요한 의존성을 설치해요. docker 사용을 권장해요.
저장소 Fork 및 clone
참고: 새 기여자는 공식 SGLang 저장소에 push할 write 권한이 없어요. GitHub 계정 아래에 저장소를 fork한 뒤 로컬에 clone하세요.
git clone https://github.com/<your_user_name>/sglang.git
# if you are using docker, the environment is already set up.
cd sglang
export PYTHONPATH=$PWD/python:$PYTHONPATH
pre-commit으로 코드 포맷
pre-commit으로 일관된 코드 스타일 검사를 유지해요. 변경 사항을 push하기 전에 다음을 실행하세요.
pip3 install pre-commit
pre-commit install
pre-commit run --all-files
- **
pre-commit run --all-files**는 설정된 모든 검사를 수동 실행하고, 가능하면 자동으로 고쳐요. 처음에 실패하면 다시 실행해서 lint 오류가 완전히 해결됐는지 확인하세요. Pull Request를 만들기 전에 코드가 모든 검사를 통과해야 해요. main브랜치에 직접 commit하지 마세요. 항상 새 브랜치(예:feature/my-new-feature)를 만들고, 변경 사항을 push한 뒤 그 브랜치에서 PR을 여세요.- lychee 링크 검사는 CI에서 강제돼요. 기본적으로 로컬 commit을 막지는 않아요.
- 로컬 링크 검사를 수동 실행하려면:
pre-commit run --hook-stage manual lychee --all-files.
테스트 실행 및 추가
모든 NPU 테스트는 end-to-end(E2E)이며 실제 모델 가중치로 서버를 띄워야 해요. 테스트는 모델 유형과 기능별로 구성된 test/registered/npu/ 아래에 있어요.
ascend/
├── llm_models/ # Per-model inference accuracy
├── vlm_models/ # Vision-language models
├── embedding_models/ # Embedding model tests
├── rerank_models/ # Reranker model tests
├── reward_models/ # Reward model tests
├── interface/ # API correctness, function calling
├── basic_function/ # Cache, sampling, quantization, etc.
└── test_npu_memory_consumption.py
테스트 추가하기
test_npu_sampling_backend.py를 완전한 예시로 보세요. 핵심 단계:
- 테스트 파일을
test/registered/npu/아래의 적절한 디렉토리에 두세요. - CI 재시도 지원을 위해 (
sglang.test.test_utils의)CustomTestCase를 상속하세요. setUpClass에서popen_launch_server()로 서버를 띄우고,tearDownClass에서kill_process_tree()로 정리하세요.register_npu_ci()로 테스트를 등록하세요:from sglang.test.ci.ci_register import register_npu_ci register_npu_ci(est_time=400, suite="stage-b-test-1-npu-a3", nightly=False) register_npu_ci(est_time=400, suite="nightly-1-npu-a3", nightly=True)
로컬에서 테스트 실행
pytest test/registered/npu/llm_models/test_npu_qwen3_0_6b.py -v
자세한 내용은 test/README.md를 참고하세요.
CI용 모델 등록
python/sglang/test/ascend/test_ascend_utils.py 목록에 없는 모델을 써야 한다면 다음 단계를 따르세요.
-
계정을 등록하고 modelscope에 모델을 업로드하세요.
-
모델이 CI 서버에 미리 캐시되고 경로
/data/ascend-ci-share-pkking-sglang/modelscope/hub/models/{your_model_repo}/{your_model}에 있는지 확인하세요. 그렇지 않다면 CI 서버에서 다음 명령을 쓰세요:modelscope download \ --model {your_model_repo}/{your_model} \ --local_dir /data/ascend-ci-share-pkking-sglang/modelscope/hub/models/{your_model_repo}/{your_model}
참고: CI 서버에 접근 권한이 없다면 담당자([email protected])에게 모델 다운로드를 요청하세요.
python/sglang/test/ascend/test_ascend_utils.py에 모델을 추가하세요(docker의"/root/.cache/modelscope/hub/models/{your_model_repo}/{your_model}"경로 사용).
문서 작성
새 기여자는 문서 작성부터 시작하는 걸 권장해요. SGLang 코드베이스를 빨리 이해하는 데 도움이 돼요. 자세한 내용은 docs/README.md를 참고하세요.
정확도 테스트
코드 변경이 모델 출력을 바꾼다면 정확도 테스트를 실행하세요. 빠른 sanity check는 few-shot GSM8K예요.
# Launch a server
python3 -m sglang.launch_server --model Qwen/Qwen2-7B-Instruct
# Evaluate. --base-url must point at the server launched above.
# The default SGLang server port is 30000; change it if you launched
# the server with a different --port.
python3 -m sglang.test.run_eval --base-url http://localhost:30000 --eval-name gsm8k --num-examples 200
위 스크립트는 주로 sanity check지 엄밀한 정확도나 속도 테스트가 아니에요. 배칭과 추론 엔진의 비결정성 때문에 정확도가 상당히 변동(1%~5%)할 수 있어요. 이 스크립트의 "Latency/Output throughput"에 의존하지 마세요 — 제대로 된 속도 테스트가 아니에요.
요즘 최신 모델에겐 GSM8K가 너무 쉬워요. 직접 더 어려운 정확도 테스트를 시도해 보세요. 추가 정확도 평가 예시는 여기서 찾을 수 있어요.
속도 벤치마크
벤치마크와 프로파일링을 참고하세요.
머지 리뷰 요청
pull request 머지 절차는 MAINTAINER.md에 설명돼 있어요. Merge Oncall, Codeowner, 그리고 다른 리뷰어들과 협력해서 승인을 받아야 해요. 그러면 PR이 머지될 수 있어요.
CI 테스트 트리거 방법
열린 PR이 많지만 CI 머신은 제한적이라 최상위·신뢰받는 기여자만 CI 테스트를 트리거할 권한이 있어요. 권한이 있는 사용자는 CI_PERMISSIONS.json에 나열돼 있어요.
PR 작성자는 CI_PERMISSIONS.json에 없어도 항상 자기 PR에서 /rerun-failed-ci를 쓸 수 있어요.
PR에서 CI가 돌려면 "run-ci" 라벨이 있어야 해요. 권한 있는 사용자는 라벨을 추가하거나 실패한 테스트를 재실행할 수 있어요. 다음 명령 중 하나를 PR에 댓글로 달면 돼요.
/tag-run-ci-label: "run-ci" 라벨을 추가해요. 이후의 커밋만 CI를 트리거하고, 현재 커밋에는 영향이 없어요.extra인자를 추가하면(/tag-run-ci-label extra) "run-ci-extra" 라벨도 붙여서 PR을 추가 테스트 워크플로(pr-test-extra.yml)에 옵트인시켜요./rerun-failed-ci: 최신 커밋에서 failed, flaky, skipped, cancelled, timed out으로 끝난 워크플로를 재실행해요./tag-and-rerun-ci: 둘 다 실행해요. 새 PR에서 현재 커밋에 CI를 시작하려면 이걸 쓰세요 —/tag-run-ci-label단독으로는 안 돼요. 같은extra인자(/tag-and-rerun-ci extra)를 받아요./rerun-test <test-spec> [<test-spec> ...]: 특정 테스트 하나 이상을 stage 경계를 무시하고 직접 재실행해요. 각<test-spec>은 pytest 스타일<file>::<TestClass>[.<test_method>]이에요(::TestClass와.<test_method>부분은 선택). 핸들러가 각 스펙을 해석하고, 등록된 runner-label별로 그룹화한 뒤, 그룹당 하나의 Rerun Test 워크플로를 디스패치해요. 예:/rerun-test test_srt_endpoint.py,/rerun-test registered/core/test_srt_endpoint.py::TestSRTEndpoint.test_simple_decode,/rerun-test test_a.py test_b.py(여러 개 동시에).
권한이 있다면 Slash Command Handler가 명령을 실행하고 댓글에 👍 반응을 달아요. 반응이 나타나기까지 몇 분 걸릴 수 있어요. 사용 예시를 보세요.
/rerun-failed-ci 댓글로 PR을 너무 많이 도배하지 않으려면, 기존 댓글을 수정하고 접미사를 붙여서(예: /rerun-failed-ci try again) 명령을 트리거할 수도 있어요.
권한이 없다면 담당자에게 CI 트리거를 요청하세요.
CI rate limit
CI 스케줄링과 제한된 리소스 때문에 우선순위가 높은 PR이 실행 중인 작업을 선점할 수 있어요. 그런 경우 테스트를 다시 실행해야 할 수 있어요. 남용을 막고 CI 리소스를 공정하게 쓰기 위해 rate limit을 적용해요.
각 CI 워크플로는 자체 구성 파일에 정의된 기본 limit이 있어요. 예를 들어 pr-gate.yml에서 기본 cooldown 기간은 120분이고, 각 워크플로는 cool-down-minutes 입력 파라미터로 덮어쓸 수 있어요.
cool-down-minutes:
description: "Cooldown period in minutes for low-permission users; 0 disables rate limiting"
type: number
default: 120
CI_PERMISSIONS.json에 있는 사용자는 사용자별 cooldown 간격을 가질 수 있어요. 실무에서는 워크플로 기본 창과 사용자별 간격 중 최솟값을 써요.
코드 스타일 가이드
- 코드 중복을 피하세요. 같은 코드 조각(5줄 초과)이 여러 번 나타나면 공유 함수로 추출하세요.
- 디바이스 동기화를 최소화하세요.
tensor.item()이나tensor.cpu()같은 비싼 CPU-NPU 동기화 연산을 가능한 줄이고, 벡터화된 코드를 쓰세요. - 극한의 효율을 우선하세요. SGLang은 런타임이고 대부분의 코드는 모든 요청의 크리티컬 패스에서 돌아요. 특히 모델 forward 코드에서 사소한 오버헤드를 최대한 줄이세요.
- 흔한 패턴은 모델 forward pass의 런타임 검사예요(예: 이것). 모든 레이어에서 거의 같을 가능성이 높아요. 가능하면
__init__에서 단일 boolean 값으로 결과를 캐시하세요.
- 흔한 패턴은 모델 forward pass의 런타임 검사예요(예: 이것). 모든 레이어에서 거의 같을 가능성이 높아요. 가능하면
- 함수를 가능한 순수하게 만드세요. 인자의 in-place 수정을 피하세요.
- 파일을 간결하게 유지하세요. 파일이 2,000줄을 넘으면 여러 작은 파일로 나누세요(예:
scheduler.py,scheduler_pp_mixin.py). - 파일 안에 핵심 데이터 구조를 파일 상단에, 유틸리티 함수를 하단에 두세요.
- 테스트가 빨리 돌게 하세요.
- 단일 테스트 파일 실행이 500초보다 길면 여러 작은 파일로 나누세요(예:
test_eagle_infer_a.py,test_eagle_infer_b.py). - github 워크플로의 단일 job이 30분보다 길면 더 작은 jobs/steps로 나누세요.
- 유닛 테스트에서 서버 실행을 재사용해서 테스트를 빨리 돌리세요.
- 단일 테스트 파일 실행이 500초보다 길면 여러 작은 파일로 나누세요(예:
pickle.loads(),pickle.load(), 또는recv_pyobj()로 신뢰할 수 없거나 네트워크에서 받은 데이터를 역직렬화하지 마세요. Python의 pickle 모듈은 안전하지 않아요 — 역직렬화 중 임의 코드를 실행할 수 있어요. msgpack이나 JSON 같은 안전한 직렬화 형식을 쓰세요.- 새 하드웨어나 기능을 지원할 때는 다음 지침을 따르세요.
- 기존 코드를 급격히 바꾸지 마세요.
- 새 하드웨어 전용 컴포넌트는 항상 새 파일로 도입하세요(예:
allocator_npu.py). - 새 기능에 if/else 블록을 여러 개 쓴다면, 공통 경로(예: NVIDIA 하드웨어 또는 기존 코드 경로)가 첫 번째 분기가 되게 하세요.
sgl-kernel-npu 업데이트 방법
sgl-kernel-npu는 Ascend NPU 전용의 별도 커널 패키지로, Ascend C와 Triton 연산자 둘 다 포함해요. sgl-kernel-npu 저장소에서 유지돼요.
연산자 개발·통합(Ascend C 디렉토리 구조, PyTorch 연산자 등록, 빌드, 테스트, 코드 스타일)에 대한 자세한 지침은 Ascend NPU 연산자 개발 가이드를 보세요.
Multi-PR 워크플로
SGLang과 sgl-kernel-npu는 별도 Python 패키지라 의존성 업데이트에 multi-PR 워크플로가 필요해요.
- sgl-kernel-npu PR 제출: 연산자 개발 가이드를 따라 sgl-kernel-npu 저장소에 연산자를 추가·수정하세요. 모든 테스트가 통과하는지 확인하세요.
- sgl-kernel-npu 버전 올리기: 버전 번호를 업데이트하세요. 머지하면 자동으로 PyPI 릴리스가 트리거돼요. 급하지 않으면 정기 릴리스(보통 1주 이내)를 기다리세요.
- SGLang에서 새 버전 참조:
docker/npu.Dockerfile의SGLANG_KERNEL_NPU_TAG인자를 새 sgl-kernel-npu 릴리스 태그로 업데이트하세요.- SGLang 코드에서 새 연산자를 사용하세요.
새 참여자를 위한 팁
기여하고 싶은데 구체적 아이디어가 없다면 "good first issue" 또는 "help wanted" 라벨이 달린 이슈를 고르세요. 이런 작업은 보통 난이도가 낮고 코드베이스를 익히는 좋은 출발점이에요.
시작 가이드로 다음 자료도 확인하세요.
- Mini-SGLang — sglang 구조를 빠르게 훑기.
- Code Walk-through — SGLang 워크플로 심층 분석.
- GTC-2026 Training Lab — 실행 중인 SGLang 인스턴스에서 최적화·벤치마크·프로파일링을 해보는 hands-on 실습.
질문이 있거나 토론을 시작하고 싶다면 Slack 채널에서 자유롭게 물어보세요.
SGLang에 관심을 가져 주셔서 감사해요. 즐거운 코딩 되세요!