문서

변환 노트

이 페이지는 일반 Core ML 내보내기를 설명합니다. 별도로 재작성된 ANE 그래프와 선택적 가중치 팔레타이제이션은 ANE_ENGINEERING.md에 문서화되어 있습니다.

내보내기는 원래 Laya 체크포인트를 FP32 PyTorch 모듈에 로드하고, 모든 state-dict 키를 엄격히 검사하고, 추론 전용 구현을 트레이싱하고, Core ML ML Program을 저장합니다. 공개된 체크포인트 파일 자체는 대부분 FP16 텐서를 담고 있습니다. 여기서 FP32는 더 높은 정밀도의 소스 가중치가 아니라 내보내기/레퍼런스 계산을 설명합니다. 학습, 가지치기, 가중치 양자화는 수행되지 않습니다. FP16은 변환 정밀도 선택이며, 진단을 위해 FP32를 고를 수 있습니다.

런타임은 체크포인트의 토크나이저, 프롬프트 레이아웃, 옵션 마커, 질문 유형 임베딩, 결정 헤드, 액션 헤드, 캘리브레이션 온도를 사용합니다. Choice, score, noul, 구조화 기준, 토큰 회계, 생성 토큰 0개는 업스트림 API를 따릅니다. 인코더는 양방향입니다. 모든 질문은 여전히 자체 인코더 시퀀스를 실행합니다. 공유 상태 은닉 상태 캐시는 없습니다.

검증된 변환 선택

  • coremltools==9.0, torch==2.7.0, numpy==2.1.3, Python 3.12.
  • 그래프 검사를 동반한 TorchScript 트레이싱, 평가 모드, FP32 모듈에 로드된 원래 가중치.
  • ML Program, macOS 15 / iOS 18 배포 대상. 실제 실행은 macOS 27.2를 실행하는 M3 Max에서 시험했습니다. iPhone/iPad와 이전 macOS 실행은 시험하지 않았습니다.
  • 기본 시퀀스 길이는 16, 32, 64, 96, 128, 192, 256, 384, 512, 768, 1024 중에서 선택되며, 체크포인트의 컨텍스트 한도로 상한이 정해집니다. 런타임은 사용 가능한 가장 작은 길이로 패딩하고 그 추가 토큰을 마스킹합니다.
  • 기본 배치 크기는 1이며, 32개의 마커 슬롯을 가집니다. 더 많은 질문은 청크로 실행됩니다. --batch-size와 --max-options는 서로 다른 내보내기 시그니처를 만듭니다.
  • 고정 셰이프는 알려진 워크로드에 사용할 수 있습니다. 내보내기의 길이나 옵션 용량을 초과하는 입력은 오류를 발생시킵니다. 더 작은 내보내기에 맞추려고 조용히 잘라내지 않습니다. 원래 체크포인트의 컨텍스트 자르기는 보존됩니다.

Apple은 TorchScript 변환과 열거형 입력 셰이프를 문서화합니다. 여러 열거형 입력은 같은 수의 셰이프를 필요로 하며 인덱스로 짝지어집니다. 이 내보내기는 그에 맞게 입력 ID와 어텐션 마스크를 짝짓습니다.

재현성을 위해 보존된 실패

이는 이 기기와 OS에서의 관찰이며, 모든 Core ML 버전에 대한 주장이 아닙니다.

  1. PyTorch의 __or__ 불리언 연산자는 변환되지 않았습니다. 명시적 torch.logical_or / torch.logical_and가 같은 마스크 의미를 보존합니다.
  2. NumPy 2.5는 coremltools 9.0 내부의 폐기된 배열-스칼라 변환을 거부했습니다. 지원되는 프로젝트 의존성은 NumPy 2.2 미만으로 고정됩니다. PyTorch는 2.7.1이 아니라 변환기가 시험한 2.7.0 버전으로 고정했습니다.
  3. 강제 CPU_AND_GPU와 함께 쓴 RangeDim은 큰 수치 오차와, 동일 입력을 반복해도 다른 결과를 냈습니다. 원래 SDPA 내보내기는 레퍼런스 답 63개 중 47개만 일치했고, 명시적 matmul/softmax 어텐션은 20/63을 일치시켰습니다. FP32도 관찰된 짧은 입력 GPU 실패를 해결하지 못했습니다. CPU / 자동 선택은 SDPA 그래프에 올바른 출력을 주었습니다.
  4. 열거형 길이는 GPU 충실도와 반복성을 회복했습니다. 이후 별도의 소형 회귀 테스트가 상수 불리언 로컬 어텐션 행렬을 슬라이스할 때 MPSGraph 컴파일러 SIGTRAP을 드러냈습니다. 진단은 ElementsAttr::getValues<bool> / FoldStridedSliceOp를 지목했습니다.
  5. 최종 구현은 정수 위치를 슬라이스하고 그 뒤에 불리언 로컬 마스크를 구성합니다. 이는 컴파일러 트랩을 제거합니다. 일반적인 RangeDim GPU 실패를 고치지는 못합니다. 이어진 실험은 여전히 49/63만 일치했고 반복 가능하지 않았습니다. 열거형 길이가 기본으로 남습니다.

런타임은 진단 실험을 위해 명시적으로 허용하지 않는 한 RangeDim + cpu_gpu를 거부합니다. 그 실패한 구성을 재현하려면:

laya-coreml convert laya-multilingual models/range-experiment --shape-mode range
python -m benchmarks.validate models/range-experiment \
  --name laya-multilingual --compute-units cpu_gpu --allow-unvalidated-gpu \
  --repeats 10 --output artifacts/range-experiment.json

이 테스트는 측정된 환경에서 실패할 것으로 예상됩니다. 원시 실패 및 성공 보고서는 benchmarks/results/에 보존되며, "passed": false를 담은 보고서는 검증된 구성으로 인용해서는 안 됩니다.

기기 증거

CPU_AND_NE는 CPU와 Neural Engine이 허용된다는 뜻이며, 모든 연산자가 Neural Engine에서 실행된다는 뜻이 아닙니다. 벤치마크는 Core ML 컴퓨트 계획의 우선/지원 기기와 추정 비용을 기록합니다. 이는 예상 계획이며, Instruments 런타임 하드웨어 트레이스나 전력 측정, 또는 배타적 Neural Engine 실행의 증명이 아닙니다.

Hub 스냅샷 로드

릴리스 스모크 테스트는 별도의 패키징 문제를 발견했습니다. 공유 Hugging Face 캐시에서 심볼릭 링크 가중치 파일을 로드하면 Core ML의 네이티브 컴파일러가 model.mlmodelc/weights/weight.bin 누락을 보고했습니다. 이에 상당하는 여섯 로컬 번들은 모두 성공적으로 로드되었습니다. 이제 런타임은 MLModel을 구성하기 전에 심볼릭 링크 기반 패키지를 일반 파일로 이루어진 콘텐츠 주소 지정 캐시로 복사합니다. 해시는 복사 전후와 재사용 시에 검사되며, 변경되거나 손상된 캐시는 오류를 발생시킵니다. 일반 파일 로컬 번들은 이 복사 경로를 거치지 않습니다. 캐시 위치와 재정의는 USAGE.md를 참조하십시오.

재현성

모든 내보내기는 coreml_config.json을 포함합니다. 원래 가중치 SHA256, 소스 리비전, 셰이프, 정밀도, 어텐션 구현, 도구 버전, 변환 시각, 모든 패키지/토크나이저/구성 파일의 해시입니다. 내보내기는 기존 디렉터리 덮어쓰기를 거부합니다. 실패한 내보내기는 새로 만든 출력 디렉터리만 제거합니다.

커밋된 골든 레퍼런스는 수정되지 않은 업스트림 Laya 리비전 573e5b62696ba441230cd6be71d593331b5d23af에서 FP32 PyTorch MPS로 생성되었습니다. 여기에는 전체 입력 토큰 ID와 반올림하지 않은 로짓이 포함됩니다. 검증은 그 토큰을 정확히 비교하고 선택 답, 캘리브레이션 확률, 액션 확률, 토큰 회계, 반복된 공개 결과를 검사합니다.

업스트림 호환 환경에서 골든 레퍼런스를 재생성하려면:

git clone https://github.com/NandhaKishorM/laya .upstream
git -C .upstream checkout 6a5819129eb220570792e417e49723d697efd76f
python -m benchmarks.reference --upstream .upstream --model-root /path/to/original/checkpoints

정확한 레퍼런스 의존성은 생성된 JSON에 기록됩니다. 이는 고정된 내보내기 환경과 별개이며, Transformers는 laya-coreml의 런타임이나 내보내기 의존성이 아닙니다.