기여 가이드

기여 가이드 (Ascend NPU)

SGLang에 오신 걸 환영해요! 기여에 관심을 가져 주셔서 감사해요. 이 가이드는 환경 설정, 테스트 실행, 문서 빌드, Pull Request(PR) 열기까지의 과정을 간결하게 정리해요. 작은 버그 수리든 큰 기능 개발이든, 이 단계들을 따라가면 매끄럽게 기여할 수 있어요.

출처: Ascend NPU 기여 가이드

소스에서 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를 완전한 예시로 보세요. 핵심 단계:

  1. 테스트 파일을 test/registered/npu/ 아래의 적절한 디렉토리에 두세요.
  2. CI 재시도 지원을 위해 (sglang.test.test_utils의) CustomTestCase를 상속하세요.
  3. setUpClass에서 popen_launch_server()로 서버를 띄우고, tearDownClass에서 kill_process_tree()로 정리하세요.
  4. 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 목록에 없는 모델을 써야 한다면 다음 단계를 따르세요.

  1. 계정을 등록하고 modelscope에 모델을 업로드하세요.

  2. 모델이 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])에게 모델 다운로드를 요청하세요.

  1. 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 값으로 결과를 캐시하세요.
  • 함수를 가능한 순수하게 만드세요. 인자의 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로 나누세요.
    • 유닛 테스트에서 서버 실행을 재사용해서 테스트를 빨리 돌리세요.
  • 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 워크플로가 필요해요.

  1. sgl-kernel-npu PR 제출: 연산자 개발 가이드를 따라 sgl-kernel-npu 저장소에 연산자를 추가·수정하세요. 모든 테스트가 통과하는지 확인하세요.
  2. sgl-kernel-npu 버전 올리기: 버전 번호를 업데이트하세요. 머지하면 자동으로 PyPI 릴리스가 트리거돼요. 급하지 않으면 정기 릴리스(보통 1주 이내)를 기다리세요.
  3. SGLang에서 새 버전 참조:
    • docker/npu.DockerfileSGLANG_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에 관심을 가져 주셔서 감사해요. 즐거운 코딩 되세요!