🤗 Kernels: 주요 업데이트
요약
Hugging Face가 새로운 리포지토리 유형인 'Kernels'를 도입하여 컴퓨팅 특화 서비스를 제공합니다. 보안 강화를 위해 Nix 기반의 재현성 확보, 코드 서명, 신뢰할 수 있는 게시자 시스템을 구축했습니다.
핵심 포인트
- 새로운 'Kernels' 리포지토리 유형 도입으로 가속기 및 OS 지원 정보 제공
- Nix를 활용한 빌드 재현성 및 샌드박스 기반 보안 강화
- 신뢰할 수 있는 게시자(Trusted Publishers) 시스템을 통한 악성 코드 방어
- 커널 발견 가능성(Discoverability) 향상 및 AI 생태계 기여
지난 몇 달 동안 우리는 이 목표를 향해 노력해 왔습니다. 그 과정에서 우리는 프로젝트를 거의 완전히 재설계했습니다. 이 포스트는 우리가 출시한 주요 업데이트와 앞으로 예정된 사항들을 요약할 것입니다.
목차
- Kernels – 새로운 리포지토리(repository) 유형
- 보안 개선
- 개편된 CLI (Command Line Interfaces)
- 프레임워크 및 백엔드(backends) 지원 범위 확대
- 에이전트형(agentic) 커널 개발을 위한 기반 마련
- 기타
- 결론
우리는 Hub에 "kernel"이라 불리는 새로운 리포지토리(repository) 유형을 도입했습니다. 이를 통해 컴퓨팅 관련 특수성을 가진 사용자들에게 맞춤형 서비스를 제공할 수 있게 되었습니다. 예를 들어, 사용자는 특정 커널에 대해 어떤 가속기(accelerators), 운영 체제(operating systems), 그리고 백엔드(backend) 버전이 지원되는지 파악할 수 있습니다:

Hub에서 사용 가능한 모든 커널은 여기에서 찾아볼 수 있습니다: https://huggingface.co/kernels.
이 커널들을 Hub의 일등 시민(first-class citizens)으로 만드는 것은 AI 생태계에도 이득이 됩니다. 이제 사용자들은 커널, 모델, 그리고 이를 사용하는 애플리케이션 전반의 트렌드를 확인할 수 있습니다. 커널의 발견 가능성(discoverability) 또한 높아집니다.
커널은 이를 로드하는 Python 프로세스와 동일한 권한으로 네이티브 코드(native code)를 실행하므로, 악성 커널은 실질적인 해를 끼칠 수 있습니다. 따라서 보안은 Kernels 프로젝트에서 항상 최우선 사항이었습니다.
이것이 우리가 초기에 재현성(reproducibility)에 집중한 이유입니다. 사용자는 커널을 직접 다시 컴파일하여 공개된 소스(source)와 일치하는지 확인할 수 있어야 합니다. 우리는 Nix를 사용하여 이를 가능하게 했는데, Nix는 빌드 레시피(build recipe)의 밀폐된 평가(hermetic evaluation)와 강력하게 격리된 샌드박스(sandbox)를 통해 빌드를 순수하게 유지하기 때문입니다. 우리는 또한 소스 Git SHA1을 커널 자체에 임베딩함으로써 출처(provenance)를 더욱 개선했습니다.
최근 몇 달 동안 우리는 신뢰할 수 있는 커널 게시자(trusted kernel publishers) 및 코드 서명(code signing)과 같은 추가적인 방어 계층을 추가했습니다.
새로운 리포지토리(repo) 유형과 함께, 저희는 "신뢰할 수 있는 게시자 (trusted publishers)"를 도입했습니다. 커널은 사용되는 Python 프로세스와 동일한 권한을 가진 머신에서 코드를 실행하기 때문에, 공격자가 악성 커널을 업로드하고 사용자가 해당 커널을 사용하도록 유도함으로써 머신을 침해할 수 있습니다. 이러한 악성 커널을 피할 수 있도록, 이제 kernels 패키지는 기본적으로 신뢰할 수 있는 게시자에 의해 생성된 커널만 로드합니다. 신뢰할 수 있는 게시자란 선의로 행동한다고 커뮤니티로부터 신뢰받는 조직을 의미합니다.
저희는 여전히 신뢰할 수 있는 게시자가 아닌 조직이나 사용자로부터 커널을 로드하는 것을 지원하고자 하지만, Hub에서 커널을 로드할 때 trust_remote_code 인자를 사용하여 명시적으로 옵트인 (opt in)해야 합니다:
from kernels import get_kernel
kernel_module = get_kernel(
"Atlas-Inference/gdn", version=1, trust_remote_code=True
...```
기본적으로 사용자는 Hub에 커널 리포지토리를 게시할 수 없습니다. 커널 게시자가 되려면 요청을 해야 합니다. 사용자와 조직은 계정 설정에서 액세스 권한을 요청할 수 있습니다. 이를 통해 저희는 이러한 요청을 사례별로 검토할 시간을 가질 수 있습니다.
저희가 추가하고 있는 또 다른 보안 계층은 코드 서명 (code signing)입니다. 코드 서명은 공격자가 Hub 자격 증명이 탈취된 신뢰할 수 있는 게시자의 커널 리포지토리에 악성 커널을 업로드하는 시나리오로부터 보호합니다. 코드 서명 방식에서는 커널이 커널 개발자만 알고 있는 개인 키 (private key)로 서명되며, 일반적으로 공개되어 있는 공개 키 (public key)로 검증됩니다. Hub 침해 시나리오에서도 공격자는 서명에 필요한 개인 키를 소유하고 있지 않기 때문에 악성 커널에 서명할 수 없습니다.
보안을 더욱 향상시키기 위해, 저희는 Sigstore의 cosign을 사용하여 일시적인 개인 키 (ephemeral private keys)로 서명합니다. 이러한 서명 키는 제한된 시간 동안만 유효하므로, 공격자가 키를 유출하더라도 일반적으로 개인 키를 사용할 수 없습니다. 또한 저희는 해당 커널이 신뢰할 수 있는 GitHub 리포지토리의 신뢰할 수 있는 GitHub 워크플로 (workflow)에 의해 서명되었는지 확인합니다.
커널 서명 (Kernel signing)은 이미 `kernel-builder`에 의해 지원되고 있으며,
커널을 검증하기 위한 `kernels verify-signature` 명령어를 제공하고 있습니다. 커널을 로드할 때 서명을 검증하는 기능은 아직 구현되지 않았는데, 이는 이 새로운 기능을 완전히 출시하기 전에 더 충분히 테스트하고 싶기 때문입니다. 자체 커널을 위한 코드 서명 (code signing) 설정에 관한 예비 참고 사항은 kernels 0.16.0 릴리스 노트에서 확인할 수 있습니다: https://github.com/huggingface/kernels/releases/tag/v0.16.0.
이전에는 많은 유틸리티들이 `kernels`와 `kernel-builder` 사이에 뒤섞여 있었습니다.
우리는 `kernels` CLI와 `kernel-builder` 사이의 더 나은 관심사 분리 (separation of concern)를 확립했습니다. 여기서의 멘탈 모델 (mental model)은 `kernels`가 커널을 로드하고 사용을 위해 준비하는 라이브러리라는 점입니다. 따라서 커널을 "빌드"하는 것과 관련된 어떤 것도 포함해서는 안 됩니다.
그 결과, `kernels`와 `kernel-builder` 모두 이제 훨씬 더 가볍고(leaner) 구체적으로 변했습니다. 이에 대해 더 자세히 알아보려면 문서를 참조하세요:
프레임워크에 대한 지원을 확장했으며, 가장 눈에 띄는 변화는 다음과 같습니다:
- kernels 및 kernel-builder에 Torch Stable ABI 지원을 추가했습니다. Torch Stable ABI를 통해 커널 개발자는 특정 Torch 버전 또는 그 이후에 출시된 버전을 약 2년 동안 대상으로 지정할 수 있습니다. 예를 들어, Torch 2.9 Stable ABI를 대상으로 하는 커널은 Torch >= 2.9를 지원합니다.
- Torch 이외에 지원되는 첫 번째 프레임워크로 Apache TVM FFI를 추가했습니다. TVM FFI는 PyTorch, Jax, CuPy와 같은 다른 프레임워크와 상호 운용되는 커널을 위한 표준화된 ABI입니다. 이를 통해 커널 개발자는 여러 프레임워크에 걸쳐 실행되는 커널을 만들 수 있습니다.
`kernel-builder`와 `kernels`는 에이전트가 처음부터 (최적화된) 커널을 만들어내는 에이전트 기반 커널 개발 (agentic kernel development)의 부상을 보완합니다. 이들은 함께 에이전트가 커널을 스캐폴딩 (scaffold), 빌드, 벤치마크하고 반복적으로 최적화할 수 있는 워크플로 (workflow)를 지원합니다.
에이전트 기반 커널 개발 (Agentic kernel development)은 아직 초기 단계이며, 적절한 개발 루프 (development loops)는 계속해서 진화할 것입니다. 따라서 사람들이 선택하여 사용하는 어떤 에이전트 워크플로 (agent workflows)나 프레임워크 (frameworks)에도 도구들이 쉽게 조합될 수 있도록, 단순하고 명확한 기본 원칙을 세우는 것이 특히 중요합니다.
`kernel-builder`는 커널 소스 코드가 스캐폴딩 (scaffolded)되어야 하는 방식과 재현 가능한 빌드 (reproducible builds)를 수행하는 데 사용되는 구조를 강제하는 데 도움을 줍니다. 이를 통해 에이전트에게 예측 가능한 프로젝트 레이아웃 (project layout)과 작동할 수 있는 반복 가능한 워크플로 (repeatable workflow)를 제공합니다. 또한 이 도구의 CLI는 에이전트에 최적화되도록 설계되었습니다. 예를 들어, 이는 비대화형 (non-interactive) 명령과 에이전트가 프로그래밍 방식으로 해석하기 쉬운 출력을 의미할 수 있습니다. 이를 위해 에이전트가 서로 다른 백엔드 (backends)의 특이성을 탐색할 수 있도록 돕는 백엔드 전용 스킬 (backend-specific skills)도 갖추고 있습니다. 이러한 스킬들은 백엔드별 툴체인 (toolchains), 컴파일 경로 (compilation paths), 그리고 성능 고려 사항 (performance considerations)을 포착할 수 있습니다.
커널을 성공적으로 빌드하는 것이 유일한 목표는 아닙니다. 우리는 그것이 대상 하드웨어 (target hardware)에서 베이스라인 (baseline) 대비 실제 속도 향상 (speedups)을 제공하는지 확인해야 합니다. 따라서 성공적인 빌드는 단지 첫 번째 검증 단계일 뿐입니다. 일반적으로 이 대상 하드웨어에는 많은 다양한 가속기 (accelerators), 심지어 동일한 가속기의 서로 다른 제품군까지 포함될 수 있습니다.
이로 인해 관련이 있는 경우 하드웨어 벤더 (hardware vendors)와 세대에 걸쳐 결과를 평가하는 것이 중요해집니다. HF Jobs와의 긴밀한 통합을 통해 이러한 벤치마킹 (benchmarking) 프로세스를 쉽게 만들 수 있습니다. 에이전트는 이 통합 기능을 사용하여 벤치마크 스위트 (benchmark suites)를 실행하고, 성능 결과 (performance results)를 수집하며, 이를 정의된 베이스라인 (baseline)과 비교할 수 있습니다.
이러한 방식을 통해 에이전트는 다양한 하드웨어 구성 (hardware configurations)에서 테스트를 실행하여 생성된 커널의 성능에 대한 신뢰할 수 있는 피드백을 얻고, 무엇을 해야 하는지 식별할 수 있습니다. 그런 피드백은 다음 최적화 반복 (optimization iteration)에 반영될 수 있습니다.
아래는 에이전트로 증강된 커널 (agent-augmented kernels)의 몇 가지 예시입니다. 이는 이 워크플로를 통해 개발 및 평가할 수 있는 커널의 종류를 보여줍니다:
`kernel-builder`를 사용한 커널 빌드를 위한 환경 설정
은(는) 매우 막막할 수 있습니다. 사용자들이 더 쉽게 사용할 수 있도록, 이제 클릭 한 번으로 환경을 설정할 수 있는 설치 스크립트(installation script)를 제공합니다. 만약 휘발성 인스턴스(ephemeral instances)를 사용하는 것을 선호한다면, 저희의 Terraform 설정 가이드를 따르는 것이 좋습니다.
커널이 빌드된 후에는, 사용 방법과 노출된 인터페이스(interfaces)를 포함한 유용한 정보를 제공하기 위해 각 커널에 대한 시스템 카드(system card)를 생성합니다. 커널이 Hub에 푸시되면, 이 시스템 카드는 커널의 프론트 매터(front matter)가 됩니다:

이는 계획을 더 잘 세우기 위해 여러 번 물어보게 될 질문입니다. 이 목적으로 `has_kernel()` 메서드를 사용하세요:
from kernels import has_kernel
print(has_kernel("kernels-community/activation", version=1))
이 메서드는 `bool`을 반환합니다. 특정 커널이 왜 지원되지 않는지에 대한 더 자세한 설명을 찾고 있다면 `get_kernel_variants()`를 사용하세요:
from kernels import get_kernel_variants, VariantAccepted
for decision in get_kernel_variants("kernels-community/activation", version=1):
name = decision.variant.variant_str
...
다음과 같이 출력될 것입니다 (사용 중인 머신에 따라 다름):
torch212-cxx11-cu130-aarch64-linux: compatible
torch210-cu128-x86_64-windows: rejected (CPU (x86_64) does not match system CPU (aarch64))
torch211-cu128-x86_64-windows: rejected (CPU (x86_64) does not match system CPU (aarch64))
...
Kernel-builder는 거의 초기부터 `manylinux_2_28`을 타겟으로 삼아왔습니다. 이전에는 glibc 2.28으로 컴파일된 현대적인 gcc 툴체인(toolchain)을 사용하여 `manylinux`를 타겟으로 삼았습니다. 오래된 버전의 `libstdc++`와의 호환성 문제를 피하기 위해, 저희는 `libstdc++`를 정적 링크(statically linked)했습니다.
하지만, 이 방식은 최근 몇 가지 문제를 일으켰습니다. 일부 `libstdc++` 기능은 전역 초기화(global initialization)를 사용합니다. 이는 PyTorch에 의해 동적으로 링크된 `libstdc++`와 `libstdc++`가 함께 작용할 때와 같이, 여러 버전의 `libstdc++`가 개입될 경우 데이터 손상(corrupted data)으로 이어질 수 있습니다.
커널에 의해 정적으로 링크(statically linked)된 경우입니다. 최근 일부 커널은 전역 초기화(global initializations)를 유발하는 기능(예: C++ 정규 표현식 (regexes))을 사용하며, 이는 데이터 손상(corrupted data)으로 이어져 세그멘테이션 결함(segfaults) 및 기타 문제를 일으킬 수 있습니다.
이 문제를 해결하기 위해, 이제 커널은 `libstdc++`를 동적으로(dynamically) 링크합니다.
이전 버전의 `libstdc++`와의 호환성을 보장하기 위해, 이제 공식 `manylinux_2_28` 툴체인(toolchain)으로 커널을 컴파일합니다.
Kernels 프로젝트의 목표는 커널 개발자와 커스텀 커널 사용자 모두에게 서비스를 제공하는 것입니다. 저희는 이를 어떻게 개선할 수 있을지에 대해 커뮤니티로부터 피드백을 받는 것을 언제나 환영합니다. 주저하지 말고 기여해 주세요!
*감사의 글: 포스트를 검토해 준 Aritra에게 감사드립니다.*
AI 자동 생성 콘텐츠
본 콘텐츠는 HuggingFace Blog의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기