View in English

  • 메뉴 열기 메뉴 닫기
  • Apple Developer
검색
검색 닫기
  • Apple Developer
  • 뉴스
  • 둘러보기
  • 디자인
  • 개발
  • 배포
  • 지원
  • 계정
페이지에서만 검색

빠른 링크

5 빠른 링크

비디오

메뉴 열기 메뉴 닫기
  • 컬렉션
  • 주제
  • 전체 비디오
  • 소개

더 많은 비디오

  • 소개
  • 요약
  • 자막 전문
  • 코드
  • Metal 4 머신 러닝과 그래픽 결합하기

    Metal 4를 사용하여 머신 러닝과 그래픽 애플리케이션을 원활하게 통합하는 방법을 알아보세요. 렌더링 및 컴퓨팅 작업과 함께 GPU 타임라인에서 모델을 실행하는 데 사용되는 텐서 리소스 및 ML 인코더를 소개합니다. 셰이더 ML을 통해 셰이더에 신경망을 직접 넣어 고급 효과를 사용하고 성능을 향상할 수 있는 방법을 알아봅니다. 또한 예제 앱을 사용하여 실제로 Metal 4 ML 워크로드용 새로운 디버깅 도구를 사용하는 방법도 보여드립니다.

    챕터

    • 0:00 - 서론
    • 2:52 - 텐서 소개
    • 6:21 - ML 네트워크 인코딩하기
    • 12:51 - 셰이더에 ML 삽입하기
    • 20:26 - ML 워크로드 디버깅하기

    리소스

    • Customizing a PyTorch operation
    • Metal Developer Resources
    • Metal Performance Shaders
      • HD 비디오
      • SD 비디오

    관련 비디오

    WWDC25

    • 몰입감 넘치는 앱을 위한 Metal 렌더링의 새로운 기능
    • Metal 4 게임 심화 기능 알아보기
    • Metal 4 게임 알아보기
    • Metal 4 살펴보기

    WWDC24

    • Apple GPU에서 머신 러닝 및 AI 모델 학습시키기
    • Metal로 머신 러닝 가속하기
  • 비디오 검색…

    안녕하세요! Apple Metal Framework 팀 엔지니어 Preston Provins입니다 나중에 동료 Scott도 함께할 예정입니다 저는 Metal 추가 기능으로서 머신 러닝과 게임의 결합을 설명하고 Scott은 Metal 4에서 머신 러닝을 위한 디버깅 경험을 향상하도록 설계된 GPU 도구 추가 기능을 소개합니다 이 세션에서 Metal 4 머신 러닝과 그래픽을 결합하는 방법을 설명해 드릴 텐데요 Metal 4의 모든 기능에 관심이 있으시다면 Metal 4 기초 세션에서 다른 Metal 4 업데이트도 알아보세요 머신 러닝은 업스케일링 애셋 압축, 애니메이션 블렌딩 신경 음영 처리와 같은 기술로 게임과 그래픽을 혁신하고 있습니다 이러한 기술은 창의성과 몰입의 경계를 확장해 줍니다 복잡한 현상을 시뮬레이션하고 시각적 정확성을 향상하며 새로운 스타일과 효과의 탐색을 간소화하는 역할을 합니다 CoreML은 세분화, 분류 생성형 AI 등 광범위한 머신 러닝 작업에 적합합니다 머신 러닝 모델을 쉽게 작성할 수 있죠 머신 러닝을 응용하는 데 GPU 타임라인과 긴밀하게 통합해야 하는 경우 Metal 4를 활용하면 문제없습니다 일반적 프레임에서 게임은 컴퓨팅 패스에서 꼭짓점 스키닝 수행 렌더링 패스에서 장면을 래스터화 다른 컴퓨팅 패스에서 안티 앨리어싱을 적용합니다 안티 앨리어싱은 일반적으로 시간 안티 앨리어싱과 같은 이미지 처리 기술로 수행됩니다 첨단 기술이 머신 러닝 네트워크로 이러한 기존 기법을 대체합니다 네트워크가 이미지를 업스케일링해 나머지 렌더링을 낮은 해상도에서 수행할 수 있기 때문에 성능이 개선됩니다

    셰이더에서 초소 규모 신경망 실행도 일반화되고 있습니다 예를 들어 기존 프래그먼트 셰이더에서는 머티리얼 텍스처를 샘플링하지만 혁신 기술에서는 소규모 신경망을 사용해 즉석에서 텍스처를 압축 해제하고 더 높은 압축률을 달성합니다 이러한 신경 렌더링 기술은 머티리얼 세트를 블록 압축식 공간의 50%로 압축합니다 이 세션에서는 머신 러닝 작업 흐름을 위한 Metal 4의 새 리소스 MTLTensor를 소개합니다 GPU 타임라인에서 다른 드로 및 디스패치와 함께 전체 네트워크를 실행하는 새로운 MTL4MachineLearningCommandEncoder를 자세히 알아보겠습니다 자체 셰이더에 머신 러닝 연산을 임베드할 수 있는 Shader ML도 소개합니다 마지막으로 Metal 디버거로 ML을 응용 프로그램에 원활하게 통합하는 방법을 설명합니다 이미 MTLBuffer와 MTLTexture에 익숙하실 텐데요 올해 Metal 4에서 소개하는 새 리소스 MTLTensor로 머신 러닝을 쉽게 데이터에 적용합니다 MTLTensor는 컴퓨팅, 그래픽 및 머신 러닝 컨텍스트에 사용 가능한 기본 머신 러닝 데이터 유형입니다 머신 러닝 워크로드는 텐서를 광범위하게 활용합니다 MTL4MachineLearningCommandEncoder는 MTLTensor로 입력과 출력을 표현하고 Shader ML은 MTLTensor로 가중치, 입력, 출력을 표현합니다

    MTLTensor는 데이터를 위한 다차원 컨테이너이며 순위와 각 순위의 차원 수로 설명됩니다 MTLTensor는 2차원을 넘어 훨씬 넓게 확장될 수 있으므로 실용적인 머신 러닝 사용에 필요한 데이터 레이아웃을 설명할 수 있다는 유연성이 있습니다 예를 들어 MTLTexture는 최대 네 개의 채널로 제한되며 텍스처 형식에 따라 범위에 엄격한 제한이 있습니다 머신 러닝은 컨볼루션 연산 등 차원이 두 개 이상인 데이터를 사용하는 것이 일반적입니다 MTLBuffer와 같은 데이터의 평면 표현을 사용하려면 차원이 여러 개인 데이터에 대해 복잡한 인덱싱 체계가 필요합니다 MTLTensor에서 다차원 데이터를 인덱싱하는 것이 훨씬 간단한데 그 이유는 각 순위의 간격과 차원이 MTLTensor 객체에 베이킹되고 자동으로 인덱싱 계산에 사용되기 때문입니다 MTLTensor를 만드는 과정을 살펴보겠습니다 MTLTensor의 순위는 축의 개수를 나타냅니다 이 MTLTensor의 순위는 2입니다 행과 열로 된 데이터가 있고요 차원의 범위는 축에 있는 데이터 포인트가 몇 개인지 설명합니다 dataType 속성은 MTLTensor가 래핑하는 데이터 형식을 정의하죠 사용 속성은 MTLTensor가 어떻게 활용될지 나타냅니다 셰이더 프로그램에서 MTL4MachineLearningCommandEncoder에 대한 MTLTensorUsageMachineLearning, 사용에 대한 MTLTensorUsageCompute 또는 MTLTensorUsageRender 등입니다 텍스처의 사용 속성 등 사용을 결합하는 것도 가능합니다 이는 MTLTensorDescriptor 객체에서 채워져야 하는 중요한 MTLTensor 속성입니다 코드로 MTLTensor를 만들어 보죠 설명자 속성이 채워지면 MTLDevice 객체에 대한 newTensorWithDescriptor:offset:error:를 호출하여 새 MTLTensor를 만듭니다 MTLTensor는 MTLDevice 또는 MTLBuffer 객체에서 생성됩니다 다만 기기에서 생성된 MTLTensor의 성능이 가장 우수합니다 MTLTexture를 섞을 수 있는 것처럼 MTLDevice 객체로 MTLTensor를 만들면 읽기와 쓰기에 최적화된 불투명한 레이아웃이 생성됩니다 이제 기존 MTLBuffer로 MTLTensor를 만드는 것을 살펴보죠 MTLDevice로 만든 MTLTensor와 달리 MTLBuffer로 만든 MTLTensor는 밀집 상태가 기본이 아닙니다 간격을 구체적으로 지정해야 하죠 가장 안쪽의 간격은 항상 하나여야 합니다 두 번째 간격은 행 인덱스가 증가할 때 건너뛸 요소의 수를 나타냅니다

    소스 MTLBuffer에는 행의 끝에 있는 미사용 열처럼 패딩이 포함될 수 있습니다 MTLTensor가 적절한 요소를 래핑 하려면 패딩을 고려해야 합니다 기본 버퍼로 MTLTensor를 만들려면 기기 할당 텐서와 마찬가지로 dataType 및 사용 속성을 설정하고 MTLTensorDescriptor의 간격 속성을 채워 결과 MTLTensor가 MTLBuffer의 콘텐츠를 적절히 래핑하게 합니다 마지막으로 소스 MTLBuffer에 newTensorWithDescriptor:offset:error:를 사용합니다 MTLTensor를 할당하고 만드는 방법을 알아보았으니 ML 작업을 GPU 타임라인에 추가하는 새 머신 러닝 인코더를 보겠습니다 Metal 4로 GPU 타임라인에 컴퓨팅 및 렌더링 명령을 쉽게 추가할 수 있습니다 MTL4ComputeCommandEncoder 및 MTL4RenderCommandEncoder를 각각 사용하면 됩니다 올해는 통합을 한 단계 더 발전시키는 차원에서 GPU 타임라인 작업에 머신 러닝 작업이 추가되었습니다 MTL4MachineLearningCommandEncoder를 사용하면 전체 모델을 함께 실행하고 GPU의 다른 Metal 명령과 동기화할 수 있으며 다른 MTLCommand와 원활하게 통합할 수 있습니다 머신 러닝 명령을 인코딩하기 위한 새로운 인코더로서 컴퓨팅 및 렌더링 인코더와 인터페이스가 유사합니다 Metal 4 동기화 프리미티브 또한 컴퓨팅 및 렌더링에서와 마찬가지로 머신 러닝 명령으로 작동합니다 동기화를 통해 작업 오케스트레이션을 제어하고 병렬화를 쉽게 수행하여 높은 성능을 유지할 수 있습니다 MTL4MachineLearningCommandEncoder 생성 작업 흐름은 둘로 나눌 수 있는데 오프라인과 런타임입니다 작업 흐름의 오프라인 부분은 응용 프로그램 출시 전에 발생하고 런타임 부분은 프레임 중간 등 응용 프로그램 수명 동안 발생합니다 작업 흐름의 오프라인 부분부터 시작해 보겠습니다 우선 MTLPackage를 만듭니다 MTLPackage는 함수 하나 이상을 위한 컨테이너로 각 함수는 ML 네트워크를 나타냅니다 Metal에서 MTLPackage로 머신 러닝 작업을 실행할 수 있습니다 이 형식은 Metal를 통한 로드 및 실행에 최적화되어 있습니다 MTLPackage를 만들려면 먼저 CoreML 패키지가 필요합니다 여기서는 CoreML 컨버터를 사용하여 PyTorch 또는 Tensorflow 등 네트워크가 작성된 ML 네트워크를 CoreML 패키지로 변환합니다 이것은 Python의 CoreML Tools 라이브러리를 사용하여 PyTorch 모델을 내보내는 예입니다 도구를 가져오고 모델에서 convert를 실행하면 내보내기가 생성됩니다 마지막으로 해당 내보내기를 ML 패키지로 저장합니다 여기서 강조하고 싶은 점을 하나 말하자면 CoreML 패키지가 꼭 ML 프로그램은 아니며 ML 프로그램만 지원됩니다 CoreML 패키지가 이전 OS로 내보낸 것이라면 이 문서에서 해당 CoreML 모델 파일을 ML 패키지로 내보내는 방법을 자세히 알아보세요 CoreML 패키지를 만든 후에는 저장된 모델에서 metal-package-builder 명령 라인을 실행하면 MTLPackage가 생성됩니다 효율적 런타임 로드 가능 형식으로 CoreML 패키지가 변환됩니다 이렇게 MTLPackage 생성을 살펴보았는데요 작업 흐름의 오프라인 부분이 완료되었고 나머지는 런타임에 수행됩니다 네트워크를 컴파일하려면 MTLPackage를 MTLLibrary로 엽니다 패키지의 네트워크를 나타내는 함수의 이름을 사용하여 함수 설명자를 만듭니다 여기에서는 주요 함수입니다 네트워크를 컴파일하기 위해 MTL4MachineLearningPipelineState를 만듭니다 이때 MTL4MachineLearningPipelineStateDescriptor와 함수 설명자를 사용합니다 네트워크에 동적 입력이 있는 경우 MTL4MachineLearningPipelineStateDescriptor에서 각 입력의 크기를 지정합니다 특정 기기에 대한 네트워크를 컴파일하려면 MTL4MachineLearningPipelineStateDescriptor를 사용해 MTL4MachineLearningPipelineState를 만듭니다

    이것이 MTL4MachineLearningPipelineState 객체를 만드는 방법입니다 이제 다음 단계는 MTL4MachineLearningCommandEncoder를 만들고 작업을 인코딩하는 것입니다 MTL4MachineLearningCommandEncoder 객체로 GPU 타임라인에서 작업을 디스패치하는 방법을 알아보죠 MTL4MachineLearningCommandEncoder 객체를 만드는데 방법은 컴퓨팅이나 렌더링을 위한 인코더를 만들 때와 같습니다 만든 MTL4MachineLearningPipelineState 객체를 설정하고 사용할 입력, 출력을 바인딩합니다 마지막으로 dispatchNetworkWithIntermediatesHeap 메서드로 작업을 디스패치합니다

    머신 러닝 인코더는 힙을 사용하여 연산 간의 중간 데이터를 저장합니다 버퍼 생성 및 릴리즈 대신 말이죠 이를 통해 다양한 디스패치에 리소스를 재사용할 수 있습니다 이 MTLHeap을 만들기 위해 MTLHeapDescriptor를 만들고 유형 속성을 MTLHeapTypePlacement로 설정하죠 파이프라인의 intermediateHeapSize를 쿼리하여 네트워크의 최소 힙 크기를 확인할 수 있습니다 힙의 크기 속성을 그 값 이상으로 설정합니다 네트워크 디스패치를 인코딩한 후 인코딩을 종료하고 명령을 제출해 GPU 타임라인에서 실행합니다

    앞서 말씀드렸듯이 Metal 4 동기화 프리미티브는 컴퓨팅 및 렌더링에서와 마찬가지로 머신 러닝 명령으로 작동합니다 머신 러닝 출력에 의존하지 않는 작업은 올바르게 동기화하면 동시에 발생할 수 있습니다

    네트워크 출력을 소모하는 작업에 한해 머신 러닝 예약 작업이 완료될 때까지 대기해야 합니다

    MTL4MachineLearningCommandEncoder 디스패치를 동기화하려면 MTLBarrier, MTLFence 등 표준 Metal 4 동기화 프리미티브를 사용합니다 새로운 MTLStageMachineLearning은 배리어에서 ML 워크로드 식별에 사용됩니다 한 예로 렌더링 작업이 네트워크 생성 출력을 대기하게 하려면 적절한 렌더링 단계와 머신 러닝 단계 사이에 배리어를 사용하면 됩니다 MTL4MachineLearningCommandEncoder의 실제 활용을 살펴보죠 이 예에서 MTL4MachineLearningCommandEncoder는 완전 컨볼루션 네트워크를 디스패치해 픽셀당 오클루전 값을 예측합니다 이를 평가하려면 신중한 동기화가 필요합니다 심도 버퍼와 보기 공간 노멀 값은 ML 워크로드를 시작하기 전에 채워집니다 네트워크가 데이터를 처리할 동안 렌더러는 다른 렌더링 관련 작업을 병렬로 디스패치하고 신경망 결과를 대기했다가 최종 프레임을 합성합니다 MTL4MachineLearningCommandEncoder는 게임의 풀 프레임 정보를 처리하는 데 국한되지 않습니다 실시간 예산에 맞는 어떤 네트워크에나 사용할 수 있으며 통합 필요에 가장 잘 맞는 방식으로 Metal 4 동기화 프리미티브를 활용할 수 있습니다 이것이 Metal 4의 MTL4MachineLearningCommandEncoder로 GPU 타임라인에서 대규모 머신 러닝 워크로드를 실행하는 방법입니다 요약하자면 머신 러닝은 MTL4MachineLearningCommandEncoder를 통해 Metal 4에서 컴퓨팅과 렌더링을 결합하는 것입니다 MTL4MachineLearningCommandEncoder를 사용하면 GPU 타임라인에서 전체 네트워크를 실행할 수 있습니다 리소스는 다른 GPU 명령과 공유할 수 있으며 강력한 Metal 4 동기화 프리미티브 세트를 사용하면 고성능 머신 러닝 기능을 구현할 수 있습니다 Metal 4는 기존 커널 및 셰이더에 소규모 머신 러닝 연산을 임베드할 수 있는 Shader ML도 도입합니다 최첨단 게임들은 머신 러닝을 도입하여 기존 렌더링 알고리즘을 대체하고 있습니다 ML 기반 기술은 전역 조명 머티리얼 음영 처리, 지오메트리 압축, 머티리얼 압축 등을 위한 솔루션을 제시할 수 있습니다 이러한 기술로 흔히 성능 향상 메모리 사용 공간 절감이 가능하죠 동기를 부여하는 예로 신경 머티리얼 압축을 보겠습니다 블록 압축식 형식과 비교했을 때 최대 50% 압축이 가능한 기술이죠 기존 머티리얼에서는 알베도, 노멀 맵 등의 머티리얼 텍스처를 샘플링합니다 그런 다음 샘플링된 값을 사용하여 음영 처리를 수행합니다 신경 머티리얼 압축에서는 잠재 텍스처 데이터를 샘플링하고 샘플링된 값을 사용해 추론을 수행하며 네트워크의 출력을 사용하여 음영 처리를 수행합니다

    각 단계를 따로 파이프라인으로 나누는 것은 텐서를 매번 기기 메모리에 동기화하고 처리한 뒤 추후 연산을 위해 출력을 다시 동기화해야 하므로 비효율적입니다

    최고의 성능을 달성하려면 앱이 이러한 단계를 단일 셰이더 디스패치로 결합해야 합니다 Shader ML을 사용하면 Metal로 프래그먼트 셰이더에서 직접 ML 네트워크를 실행할 수 있으며 단계 사이마다 기기 메모리를 거칠 필요가 없습니다 입력 텐서를 초기화하고 네트워크를 실행하며 각 프레임에 필요한 픽셀만 음영 처리하면 됩니다 덕분에 런타임 메모리 사용 공간과 게임의 디스크 공간이 개선됩니다 신경 머티리얼 평가를 더 자세히 살펴보겠습니다 입력 MTLTensor 초기화는 두 부분으로 나눌 수 있습니다 네트워크 가중치 로드와 입력 기능 MTLTensor 빌드입니다 입력 기능 MTLTensor는 바인딩된 텍스처를 프래그먼트의 UV 좌표로 샘플링하여 만들어집니다

    입력 기능 MTLTensor가 학습된 가중치 행렬에 의해 변환돼 기능 추출, 활성화 계산, 계층을 통한 정보 전파에 추론이 진행되죠 이 평가는 여러 계층에 대해 반복되며 압축 해제된 머티리얼이 나옵니다 마지막으로 압축 해제된 머티리얼을 사용하여 프래그먼트의 음영 처리 계산을 수행합니다

    Shader ML로 입력 MTLTensor를 초기화하는 방법을 살펴보겠습니다 먼저 Shader ML을 활용할 프래그먼트 셰이더를 선언하고 네트워크 가중치를 전달하겠습니다 우선 새로운 metal_tensor 헤더를 포함합니다 MTLTensor 유형을 사용하여 네트워크 가중치에 접근합니다 MTLTensor는 버퍼 바인딩 슬롯을 사용해 셰이더에 바인딩됩니다 인수 버퍼를 사용하여 MTLTensor를 전달할 수도 있습니다 MTLTensor 유형은 템플릿화됩니다 첫 번째 템플릿 인수는 MTLTensor의 dataType입니다 이 MTLTensor가 기기 메모리에 생성되었으므로 기기 주소 공간 한정자를 사용합니다 두 번째 인수는 MTLTensor의 차원과 MTLTensor에 인덱싱하는 데 사용할 유형을 나타냅니다 여기서는 dextents를 사용해 동적 범위 2순위 텐서를 정의합니다 프래그먼트 셰이더가 설정되었습니다 그러면 신경 머티리얼 압축 알고리즘을 구현해 보겠습니다 네트워크의 가중치를 전달하면 네 가지 잠재 텍스처를 샘플링하여 입력 MTLTensor를 만들 수 있습니다 MTLTensor는 바인딩할 수 있는 리소스만은 아닙니다 셰이더에서 직접 인라인 MTLTensor를 생성할 수 있습니다! 샘플링된 값을 래핑하는 MTLTensor를 만들고 이를 네트워크 평가에 사용합니다 인라인 MTLTensor는 기본적으로 밀집 상태로 보므로 생성 단계에서 간격을 전달할 필요가 없습니다 이렇게 입력 MTLTensor 초기화가 완료되었습니다 이제 신경망의 값을 추론할 준비가 끝났습니다 평가에서는 학습된 매개변수로 입력을 변환한 다음 활성화합니다 활성화는 다음 계층으로 전달되고 최종 계층의 활성화가 압축 해제된 머티리얼을 형성하죠

    올해 Metal에는 음영 처리 언어에서 MTLTensor 연산에 접근할 수 있도록 Metal 성능 프리미티브가 도입되었습니다 이 라이브러리는 MTLTensor에서 성능 이식형 솔루션을 구현할 수 있는 고성능 API 세트로 행렬곱과 컨볼루션 연산을 제공하죠 행렬곱은 신경망 평가의 핵심입니다 Metal 성능 프리미티브에서 제공된 matmul2d 구현을 사용하여 성능 이식형 네트워크 평가 루틴을 구현하겠습니다 우선 Metal 셰이더에 새 MetalPerformancePrimitives 헤더를 포함합니다 행렬곱의 매개변수는 matmul2d_descriptor 객체를 사용해 구성됩니다 첫 번째 템플릿 매개변수 세트는 행렬곱의 문제 크기를 지정합니다 다음 템플릿 매개변수 세트는 연산을 수행할 때 행렬곱에 대한 입력을 치환해야 하는지 여부를 제어합니다 마지막 템플릿 매개변수는 정밀도 요구 사항을 제어합니다

    설명자 외에도 matmul2d 연산은 연산에 참여할 스레드 수로 특수화해야 합니다 현재 프래그먼트 셰이더에 있으니 execution_thread를 사용해 이 스레드가 전체 행렬곱을 수행함을 나타내겠습니다 그런 다음 해당 구성으로 행렬곱을 실행합니다

    마지막으로 ReLU 활성화 함수를 사용하여 행렬곱 결과의 각 요소를 활성화합니다 이 과정은 두 번째 계층에서도 반복되어 셰이더에서 바로 네트워크를 전체 평가합니다 평가가 완료되면 압축 해제된 머티리얼을 음영 처리에 사용할 수 있습니다 출력 MTLTensor는 채널 정보를 보유하는데 이 정보는 텍스처에서 샘플링한 다른 값처럼 사용할 수 있습니다 이것은 기존 머티리얼과 비교한 신경 머티리얼 압축의 실시간 데모입니다 신경 머티리얼로 인한 품질 손실이 느껴지지 않으며 특히 음영 처리 후 그러합니다 기본 색상을 따로 나타낸 모습인데 여전히 신경 머티리얼과 기존 머티리얼 사이의 차이점이 거의 눈에 띄지 않습니다 하지만 사용 메모리는 절반, 차지 디스크 공간은 절반에 불과합니다

    MTLTensor 연산은 프래그먼트 셰이더에 국한되지 않습니다 모든 함수와 모든 셰이더 단계에서 사용할 수 있습니다 전체 simdgroup이나 threadgroup이 동일한 데이터에 동일한 연산을 수행한다면 큰 실행 그룹을 선택해 하드웨어를 더 유리하게 활용할 수 있습니다 그러나 MTLTensor 연산이 데이터와 관련하여 분기가 있거나 MTLTensor 연산 호출 사이트에서 비균일한 제어 흐름을 보이는 경우 단일 스레드 실행 그룹을 사용해야 합니다 다른 실행 체계에서는 분기가 없고 실행 그룹의 제어 흐름이 균일하다고 가정합니다 요약하자면 이제 자체 셰이더에서 행렬곱 및 컨볼루션과 같은 ML 연산을 수행할 수 있습니다 Shader ML로 단일 셰이더에서 여러 ML 연산을 쉽게 수행 가능합니다 캐시 친화적이며 필요한 디스패치 횟수가 감소하고 사용 메모리 대역폭이 줄어듭니다 특히 소규모 네트워크 사용 시에요 또한 Shader ML을 사용하면 맞춤형 연산을 만드는 데 필요한 세밀한 제어가 가능합니다 Metal 앱에서 최첨단 ML 기술을 구현하기가 매우 쉬워졌습니다 바로 Shader ML을 사용하여 셰이더 프로그램에 신경망을 임베드하는 방법이죠 지금부터는 동료 Scott이 Metal 4의 디버깅 도구로 머신 러닝 워크로드를 쉽게 디버깅하는 방법을 설명해 드리겠습니다 네, GPU Tools 팀의 소프트웨어 엔지니어 Scott Moyers입니다 앞서 Preston이 머신 러닝으로 앰비언트 오클루전을 계산하는 응용 프로그램을 보여 드렸죠 이 앱은 머신 러닝 네트워크를 Metal 렌더링 파이프라인에 직접 인코딩합니다 이 앱의 개발을 돕는 과정에서 출력에 심각한 아티팩트가 발생하는 문제가 생겼습니다 문제가 확실히 보이게 앰비언트 오클루전 패스만 활성화하겠습니다 물체의 모서리에 그림자가 있어야 하는데 대신 노이즈가 많고 장면의 구조가 거의 보이지 않죠 새 도구로 이 문제를 찾고 해결한 방법을 보여 드리겠습니다 먼저 Xcode에서 앱의 GPU 추적을 캡처합니다 이를 위해 화면 하단의 Metal 아이콘을 클릭한 다음 캡처 버튼을 클릭합니다

    캡처가 완료되면 요약에서 캡처 프레임을 확인할 수 있습니다 왼쪽의 디버깅 탐색기에는 프레임을 구성하기 위해 응용 프로그램에서 사용한 명령 목록이 있습니다 한 예로 오프스크린 명령 버퍼에는 G-buffer 패스를 포함해 많은 인코더가 포함되어 있습니다 다음 명령 버퍼에는 MTL4MachineLearningCommandEncoder가 포함되어 있습니다 Metal 4를 사용해 동기화를 세밀하게 제어할 수 있었는데요 종속 패스 간의 배리어와 이벤트를 주의 깊게 설정하기는 했지만 동기화가 원인일 수 있겠다는 생각이 들었습니다 확인차 종속성 뷰어를 사용하기로 했습니다 Metal 응용 프로그램 구조의 개요를 확인하는 데 유용한 도구죠 왼쪽 상단의 종속성 아이콘을 클릭하겠습니다

    이 인터페이스를 사용하면 응용 프로그램의 모든 명령과 배리어, 이벤트 등의 동기화 프리미티브를 볼 수 있습니다 명령 인코더를 확대하면 더 자세히 볼 수 있습니다 첫 번째 명령 버퍼가 완성된 지점이 있고요

    그 아래의 명령은 노멀 값을 MTLTensor로 복사합니다 이어서 배리어가 있고 그 뒤에 MTL4MachineLearningCommandEncoder가 있습니다 전체적인 구조를 검토하기 위해 다시 축소하겠습니다 새로운 앰비언트 오클루전 패스는 오른쪽의 명령 버퍼에 있습니다 이 패스를 추가하기 전에는 응용 프로그램이 잘 작동했습니다 그래서 상단 및 하단 명령 버퍼의 종속성은 정상이라고 가정할 수 있습니다 MTL4MachineLearningCommandEncoder를 포함하는 새로운 명령 버퍼를 검사해 보죠

    명령 버퍼가 시작되기 전에 공유 이벤트 신호 대기 지점이 있습니다 명령 버퍼의 끝에는 다음 명령 버퍼 차단 해제 신호가 있습니다 따라서 이 명령 버퍼와 병렬로 다른 명령을 실행할 수 없습니다 그리고 명령 버퍼의 내부에서 각 인코더 사이에 배리어가 있어 각 명령이 차례로 실행되도록 합니다 저는 이 단계에서 최소한 이 프레임은 동기화 문제가 없다고 확신했습니다 이 부분을 배제하고 MTL4MachineLearningCommandEncoder를 바로 확인하기로 했습니다 앰비언트 오클루전 네트워크에 대한 디스패치 호출을 클릭하면 바인딩된 리소스로 이동합니다 오른쪽의 보조 편집기에 MTLTensor 출력이 있습니다 실행 중인 응용 프로그램과 동일한 아티팩트가 있군요 분명히 문제입니다 입력 MTLTensor를 두 번 클릭하여 출력 옆에 표시되도록 하겠습니다 입력에는 보기 공간 노멀 값에 예상되는 내용이 그대로 있습니다 다른 방향을 바라보는 물체는 구성 요소의 강도가 다릅니다 따라서 문제는 머신 러닝 네트워크 내부에 있는 것이 확실합니다 바인딩된 리소스 보기로 돌아가서 네트워크를 두 번 클릭하여 새 ML 네트워크 디버거에서 엽니다 이 도구는 모델 내부의 상황을 이해하는 데 필수적입니다

    이 그래프는 앰비언트 오클루전 네트워크의 구조를 나타냅니다 PyTorch로 작성한 것인데 대상의 빌드 단계에서 Preston이 앞서 제안한 바에 따라 CoreML 패키지로 내보낸 다음 MTLPackage로 변환합니다 상자는 연산에 해당하며 연결은 데이터가 모델을 왼쪽에서 오른쪽으로 흐르는 것을 보여 주죠 제 목표는 아티팩트를 유발한 연산을 찾는 것이었습니다 최종 출력에 문제가 있고 입력은 정상임을 알았으므로 그래프를 이등분하여 범위를 좁혀 보기로 했습니다 중간쯤에 있는 연산을 선택해 보겠습니다 연산을 선택하면 오른쪽에 해당 설명과 속성, 입력 및 출력이 표시됩니다 게다가 연산에서 출력되는 중간 MTLTensor 데이터를 검사할 수 있습니다 미리보기를 클릭하여 MTLTensor 뷰어에서 열겠습니다 여기에 이미 아티팩트가 있으니 이전 연산을 확인해 보겠습니다

    이 연산의 출력에도 아티팩트가 있습니다 이것의 입력을 살펴보겠습니다

    이 MTLTensor는 장면의 가장자리를 강조하는 것으로 보입니다 예상에 부합하고요 네트워크에 대한 입력은 심도 버퍼에서 추출된 가장자리죠 따라서 네트워크의 이 영역에 문제가 있는 것입니다

    이 스티칭된 영역은 연산의 왼쪽 상단에 있는 화살표를 클릭하여 확장할 수 있습니다

    이러한 연산의 순서와 유형으로 보아 SignedSmoothstep 함수라는 것을 알 수 있습니다 이 함수는 먼저 입력의 절대값을 구합니다 그리고 값을 0과 1 사이로 고정하죠 하지만 이후 결과를 자체 거듭제곱하고 있습니다 올바르지 않죠 SignedSmoothstep 함수에 거듭제곱 연산은 없었을 텐데요 Python 코드로 들어가서 무슨 상황인지 알아보죠 디버깅 세션을 중단하고 소스 코드로 돌아가겠습니다

    실행 중인 모델은 LightUNet이라는 클래스에 있습니다 순전파 함수가 제대로 동작하는지 확인코자 해당 함수로 이동합니다

    함수가 수행 중인 첫 맞춤 연산은 SignedSmoothstep인데 ML 네트워크 디버거에서 봤던 스티칭된 영역입니다 순전파 함수로 넘어가겠습니다

    입력의 부호를 유지하는 간단한 smoothstep 연산이어야 하는데요 하지만 이 줄에서 버그가 보입니다 별표를 너무 많이 입력해 곱셈 연산자가 거듭제곱이 되었습니다 불필요한 별표를 삭제하고 다시 실행해 보겠습니다

    이렇게 Metal 4의 내장 MTL4MachineLearningCommandEncoder를 사용하여 신경 앰비언트 오클루전을 정상적으로 구현했습니다

    이 데모에서는 Metal 디버거로 Metal 4 머신 러닝 응용 프로그램을 디버깅한 방법을 보여 드렸습니다 먼저 종속성 뷰어로 동기화를 검증했고요 이어서 MTLTensor 뷰어를 사용해 네트워크의 입력, 출력을 검사했죠 그 결과 문제가 네트워크 내부에 있었음이 확인되었습니다 마지막으로 ML 네트워크 디버거를 사용하여 단계적으로 네트워크의 연산을 확인하며 정확한 문제 위치를 파악했습니다

    이러한 도구는 더 큰 도구 제품군의 일부로서 Metal 앱을 디버깅하고 최적화하는 데 사용할 수 있습니다 이제 오늘 내용을 요약해 볼까요 Metal 4는 머신 러닝 데이터용으로 특수 설계된 새로운 다차원 리소스 MTLTensor를 도입합니다 MTLTensor로 2차원을 넘는 복잡한 데이터 레이아웃이 유연해지고 내재된 간격과 차원 정보 덕분에 인덱싱이 크게 간소화됩니다 Metal 4의 새로운 기능을 통해 머신 러닝 워크로드를 Metal 파이프라인에 결합할 수 있습니다 MTL4MachineLearningCommandEncoder를 사용하면 전체 머신 러닝 네트워크를 GPU 타임라인에서 직접 실행할 수 있습니다 덕분에 컴퓨팅 및 렌더링 작업과 원활하게 통합하고 동기화할 수 있습니다 소규모 네트워크의 경우 Shader ML과 Metal 성능 프리미티브 라이브러리를 사용해 머신 러닝 연산을 셰이더에 직접 임베드할 수 있습니다 마지막으로 Metal 디버거로 Metal 4 응용 프로그램의 내부 상황을 더 명확하게 확인할 수 있습니다 새로운 ML 네트워크 디버거를 통해 네트워크와 네트워크가 기기에서 실행되는 방식을 쉽게 이해할 수 있습니다 이러한 인사이트는 정확성과 성능 최적화에 필수입니다 다음 단계로 최신 OS와 Xcode를 설치하여 Metal 4의 MTL4MachineLearningCommandEncoder와 Shader ML을 직접 사용해 보세요 자세한 내용은 Apple Developer 웹사이트의 Metal 개발자 도구를 참고하세요 Metal 4 응용 프로그램을 최대한 활용하려면 다른 Metal 4 세션도 확인해 보세요 이러한 새로운 기능으로 무엇을 빌드하실지 기대됩니다 감사합니다

    • 8:13 - Exporting a Core ML package with PyTorch

      import coremltools as ct
      
      # define model in PyTorch
      # export model to an mlpackage
      
      model_from_export = ct.convert(
          custom_traced_model,
          inputs=[...],
          outputs=[...],
          convert_to='mlprogram',
          minimum_deployment_target=ct.target.macOS16,
      )
      
      model_from_export.save('model.mlpackage')
    • 9:10 - Identifying a network in a Metal package

      library = [device newLibraryWithURL:@"myNetwork.mtlpackage"];
      
      functionDescriptor = [MTL4LibraryFunctionDescriptor new]
      functionDescriptor.name = @"main";
      functionDescriptor.library = library;
    • 9:21 - Creating a pipeline state

      descriptor = [MTL4MachineLearningPipelineDescriptor new];
      descriptor.machineLearningFunctionDescriptor = functionDescriptor;
      
      [descriptor setInputDimensions:dimensions
                       atBufferIndex:1];
      
      pipeline = [compiler newMachineLearningPipelineStateWithDescriptor:descriptor
                                                                   error:&error];
    • 9:58 - Dispatching a network

      commands = [device newCommandBuffer];
      [commands beginCommandBufferWithAllocator:cmdAllocator];
      [commands useResidencySet:residencySet];
      
      /* Create intermediate heap */
      /* Configure argument table */
      
      encoder = [commands machineLearningCommandEncoder];
      [encoder setPipelineState:pipeline];
      [encoder setArgumentTable:argTable];
      [encoder dispatchNetworkWithIntermediatesHeap:heap];
    • 10:30 - Creating a heap for intermediate storage

      heapDescriptor = [MTLHeapDescriptor new];
      heapDescriptor.type = MTLHeapTypePlacement;
      heapDescriptor.size = pipeline.intermediatesHeapSize;
              
      heap = [device newHeapWithDescriptor:heapDescriptor];
    • 10:46 - Submitting commands to the GPU timeline

      commands = [device newCommandBuffer];
      [commands beginCommandBufferWithAllocator:cmdAllocator];
      [commands useResidencySet:residencySet];
      
      /* Create intermediate heap */
      /* Configure argument table */
      
      encoder = [commands machineLearningCommandEncoder];
      [encoder setPipelineState:pipeline];
      [encoder setArgumentTable:argTable];
      [encoder dispatchNetworkWithIntermediatesHeap:heap];
      
      [commands endCommandBuffer];
      [queue commit:&commands count:1];
    • 11:18 - Synchronization

      [encoder barrierAfterStages:MTLStageMachineLearning
                beforeQueueStages:MTLStageVertex
                visibilityOptions:MTL4VisibilityOptionDevice];
    • 15:17 - Declaring a fragment shader with tensor inputs

      // Metal Shading Language 4
      
      #include <metal_tensor>
      
      using namespace metal;
       
      [[fragment]]
      float4 shade_frag(tensor<device half, dextents<int, 2>> layer0Weights [[ buffer(0) ]],
                        tensor<device half, dextents<int, 2>> layer1Weights [[ buffer(1) ]],
                        /* other bindings */)
      {
          // Creating input tensor
          half inputs[INPUT_WIDTH] = { /* four latent texture samples + UV data */ };
      
          auto inputTensor = tensor(inputs, extents<int, INPUT_WIDTH, 1>());
          ...
      }
    • 17:12 - Operating on tensors in shaders

      // Metal Shading Language 4
      
      #include <MetalPerformancePrimitives/MetalPerformancePrimitives.h>
      
      using namespace mpp;
      
      constexpr tensor_ops::matmul2d_descriptor desc(
                    /* M, N, K */ 1, HIDDEN_WIDTH, INPUT_WIDTH,
             /* left transpose */ false,
            /* right transpose */ true,
          /* reduced precision */ true);
      
      tensor_ops::matmul2d<desc, execution_thread> op;
      op.run(inputTensor, layerN, intermediateN);
      
      for (auto intermediateIndex = 0; intermediateIndex < intermediateN(0); ++intermediateIndex)
      {
          intermediateN[intermediateIndex, 0] = max(0.0f, intermediateN[intermediateIndex, 0]);
      }
    • 18:38 - Render using network evaluation

      half3 baseColor          = half3(outputTensor[0,0], outputTensor[1,0], outputTensor[2,0]);
      half3 tangentSpaceNormal = half3(outputTensor[3,0], outputTensor[4,0], outputTensor[5,0]);
      
      half3 worldSpaceNormal = worldSpaceTBN * tangentSpaceNormal;
      
      return baseColor * saturate(dot(worldSpaceNormal, worldSpaceLightDir));
    • 0:00 - 서론
    • 게임과 그래픽에서 머신 러닝(ML) 통합을 강화하는 Metal 4를 소개합니다. Metal 4는 ML 네트워크를 사용하여 업스케일링, 애셋 압축, 애니메이션 블렌딩과 같은 기술을 지원하여 성능과 시각적 정확성을 향상시킵니다. 주요 기능으로는 ML 워크플로를 위한 ‘MTLTensors’, GPU 타임라인에서 네트워크를 실행하기 위한 ‘MTL4MachineLearningCommandEncoder’, 셰이더에 ML 작업을 내장하기 위한 Shader ML, 개선된 디버깅 도구가 있습니다. CoreML은 ML 모델을 작성하는 데 최적화되어 있고 Metal Debugger의 도움을 받아 애플리케이션에 원활하게 ML을 통합할 수 있습니다.

    • 2:52 - 텐서 소개
    • Metal 4에서는 머신 러닝 워크로드를 위해 특별히 설계된 새로운 리소스인 ‘MTLTensor’가 도입됩니다. ‘MTLTensor’는 다차원 데이터 컨테이너로, 머신 러닝에 일반적으로 사용되는 복잡한 데이터 레이아웃(예: 합성 연산에 필요한 데이터)을 효율적으로 표현할 수 있습니다. ‘MTLBuffers’와 같은 평면적 표현에 비해 다차원 데이터 인덱싱이 간소화됩니다. ‘MTLTensor’는 순위(축 수), 범위(각 축을 따라 데이터 포인트 수), 데이터 유형, 사용량 속성으로 정의됩니다. 이러한 속성은 ‘MTLTensorDescriptor’ 객체에 지정됩니다. 최적화된 성능과 불투명한 레이아웃을 제공하는 ‘MTLDevice’ 객체 또는 잠재적 패딩을 고려하여 스트라이드를 지정해야 하는 기존 ‘MTLBuffer’ 객체에서 ‘MTLTensors’를 생성할 수 있습니다.

    • 6:21 - ML 네트워크 인코딩하기
    • 최신 Metal에서는 ‘MTL4MachineLearningCommandEncoder’도 도입되어 머신 러닝 작업을 컴퓨팅 및 렌더링 명령과 함께 GPU 타임라인에 원활하게 통합할 수 있습니다. 이러한 새로운 인코더를 사용하면 전체 ML 모델을 GPU에서 실행하고 장벽 및 울타리와 같은 표준 동기화 기본 요소를 사용하여 다른 Metal 명령과 동기화할 수 있습니다. 워크플로는 오프라인 및 런타임 등 두 가지 주요 부분으로 구성됩니다. 오프라인에서 시스템은 ‘metal-package-builder’ 명령줄 툴을 사용하여 CoreML 패키지를 최적화된 ‘MTLPackage’로 변환합니다. 런타임 시 시스템은 ‘MTLPackage’를 ‘MTL4MachineLearningPipelineState’로 컴파일하고, 파이프라인 상태, 입력, 출력으로 설정된 ‘MTL4MachineLearningCommandEncoder’를 생성한 다음 인코딩된 명령을 GPU에 전송합니다. 인코더는 ‘MTLHeap’을 활용하여 중간 데이터를 저장함으로써 리소스 사용을 최적화합니다. 이를 통해 종속되지 않은 작업의 병렬 실행이 가능해져 성능이 향상됩니다. Metal 4의 동기화 기능은 ML 출력을 소모하는 작업이 네트워크가 완료될 때까지 기다리도록 보장하기 때문에 게임뿐만 아니라 다양한 실시간 애플리케이션에 적합합니다.

    • 12:51 - 셰이더에 ML 삽입하기
    • Metal 4는 Shader ML을 도입하여 개발자가 머신 러닝 작업을 셰이더에 직접 내장할 수 있게 지원합니다. 이렇게 하면 기기 메모리와 셰이더 간에 텐서를 동기화할 필요성이 없어져 성능이 향상되고 메모리 사용량이 줄어듭니다. 특정 ML 기술인 신경 물질 압축이 그 예입니다. 기존 블록 압축 형식 대비 최대 50%까지 재질 텍스처를 압축합니다. Shader ML을 사용하면 입력 텐서 초기화부터 추론 및 음영 수행까지 전체 신경 물질 평가 프로세스를 단일 셰이더 디스패치로 결합할 수 있습니다. Metal Performance Primitives는 Shader ML에 통합되어 행렬 곱셈 및 컨볼루션 같은 고성능 API를 제공합니다. 이를 통해 프래그먼트 셰이더 내에서 신경망 평가 루틴을 효율적으로 구현함으로써 인지되는 품질 손실 없이 실시간 애플리케이션을 얻을 수 있지만, 메모리 사용량과 디스크 공간은 크게 줄어듭니다.

    • 20:26 - ML 워크로드 디버깅하기
    • 제공된 예제에서 Xcode의 새로운 GPU Tools를 사용하면 애플리케이션의 주변 오클루전 계산에서 심각한 아티팩트를 발생시키는 머신 러닝 워크로드를 디버깅할 수 있습니다. GPU 추적을 캡처하고 종속성 뷰어를 활용하여 명령 버퍼의 동기화를 검사하여 문제를 배제할 수 있습니다. 그런 다음 ‘MTL4MachineLearningCommandEncoder’의 입력 및 출력 텐서를 검토하여 문제가 머신 러닝 네트워크 자체 내에 있는지 확인합니다. 다음으로, 모델 구조를 나타내는 시각적 도구인 새로운 ML 네트워크 디버거에서 네트워크를 열 수 있어 PyTorch로 작성되어 CoreML 및 MTLPackage로 전환되었으며 아티팩트를 유발한 특정 작업을 정확히 찾아낼 수 있습니다. 그래프를 검사해 보면 출력과 이전 작업의 입력 모두에 아티팩트가 존재하여 네트워크 내에 문제가 있음을 나타냅니다. ‘SignedSmoothstep’ 기능이 문제 영역으로 확인되었습니다. Python 코드를 검토한 결과, 버그가 발견되었습니다. 별표가 하나 더 추가되어 시스템이 곱셈 연산을 제곱 연산으로 해석하게 됩니다. 이 오류를 수정하면 문제가 해결되고 Metal 4의 ‘MTL4MachineLearningCommandEncoder’를 사용한 신경형 주변 오클루전 구현이 성공적으로 디버깅됩니다.

Developer Footer

  • 비디오
  • WWDC25
  • Metal 4 머신 러닝과 그래픽 결합하기
  • 메뉴 열기 메뉴 닫기
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    메뉴 열기 메뉴 닫기
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    메뉴 열기 메뉴 닫기
    • 손쉬운 사용
    • 액세서리
    • 앱 확장 프로그램
    • App Store
    • 오디오 및 비디오(영문)
    • 증강 현실
    • 디자인
    • 배포
    • 교육
    • 서체(영문)
    • 게임
    • 건강 및 피트니스
    • 앱 내 구입
    • 현지화
    • 지도 및 위치
    • 머신 러닝 및 AI
    • 오픈 소스(영문)
    • 보안
    • Safari 및 웹(영문)
    메뉴 열기 메뉴 닫기
    • 문서(영문)
    • 튜토리얼
    • 다운로드(영문)
    • 포럼(영문)
    • 비디오
    메뉴 열기 메뉴 닫기
    • 지원 문서
    • 문의하기
    • 버그 보고
    • 시스템 상태(영문)
    메뉴 열기 메뉴 닫기
    • Apple Developer
    • App Store Connect
    • 인증서, 식별자 및 프로파일(영문)
    • 피드백 지원
    메뉴 열기 메뉴 닫기
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program(영문)
    • News Partner Program(영문)
    • Video Partner Program(영문)
    • Security Bounty Program(영문)
    • Security Research Device Program(영문)
    메뉴 열기 메뉴 닫기
    • Apple과의 만남
    • Apple Developer Center
    • App Store 어워드(영문)
    • Apple 디자인 어워드
    • Apple Developer Academy(영문)
    • WWDC
    Apple Developer 앱 받기
    Copyright © 2025 Apple Inc. 모든 권리 보유.
    약관 개인정보 처리방침 계약 및 지침