6년 된 애플워치에서 진짜 LLM을 돌려봤습니다

BBetter Stack
컴퓨터/소프트웨어가전제품/카메라

스크립트

00:00:00애플 워치 시리즈 6에서 완전히 오프라인으로 실행 중인 LLM AI 모델입니다.
00:00:072020년에 출시된 6년 된 시계죠.
00:00:11클라우드 스트리밍은 전혀 사용되지 않습니다.
00:00:14모든 것이 엣지에서 작동하며 초당 평균 약 15토큰의 텍스트를 스트리밍합니다.
00:00:20그래서 며칠 전에 애플 워치가 실제로 AI 모델을 로컬에서 실행할 수 있는지 직접 테스트해 보았습니다.
00:00:27놀랍게도 정말 가능하더군요.
00:00:30몇 가지 요령을 쓰면 꽤 효율적으로 만들 수도 있습니다.
00:00:33이게 가능한 이유는 백그라운드에서
00:00:36Falcon H1이라는 9천만 개 파라미터 모델이 실행되고 있기 때문입니다.
00:00:41크기가 워낙 작다 보니 놀라울 정도로 성능이 잘 나옵니다.
00:00:44심지어 툴 호출도 지원하죠.
00:00:46그리고 워치 자체의 음성 입력 덕분에 프롬프트를 입력하기도 정말 쉽습니다.
00:00:51따라서 오늘 영상에서는 애플 워치에서 AI 모델을
00:00:55어떻게 컴파일하고 로컬로 실행하는지 살펴보겠습니다.
00:00:58왜 이게 가능한지, 그리고 이러한 모델을 배포할 때 모범 사례는 무엇인지 이야기해 볼 거고요.
00:01:03간단한 데모를 통해 성능이 어덯게 나오고 어디에서 여전히 버벅이는지 확인해 보겠습니다.
00:01:08아주 재미있을 겁니다.
00:01:10그럼 바로 시작해 보죠.
00:01:15몇 달 전에 1세대 라즈베리 파이가 AI 모델을 완전히 오프라인으로 실행할 수 있는지 테스트하는 영상을 올렸었습니다.
00:01:23결과부터 말하자면 가능하긴 하더군요.
00:01:25하지만 테스트 당시 초당 0.3토큰 정도로 상당히 버벅였습니다.
00:01:30작동은 하지만 실제로 쓰기엔 무리가 있었죠.
00:01:33그러다 문득 '이 똑같은 모델을 6년 된 내 애플 워치에 넣으면 어떻게 될까?' 하는 생각이 들었습니다.
00:01:38제대로 된 애플 웨어러블 기기에서는 어느 정도 성능이 나올까요?
00:01:43결과는 무려 50배 이상 빠른 것으로 나타났습니다.
00:01:46라즈베리 파이 1은 700MHz 코어 하나에 512MB 램을 탑재한 반면,
00:01:54시리즈 6은 1.8GHz 듀얼 코어에 1기가바이트 램을 탑재하고 있습니다.
00:02:00따라서 서류상으로는 애초부터 훨씬 강력한 사양이었죠.
00:02:04하지만 이렇게까지 성능 차이가 크게 날 줄은 몰랐습니다.
00:02:07자, watchOS 기기에서 추론을 실행하는 방법에 대해 고민해 본다면
00:02:12가장 먼저 자연스럽게 떠오르는 것은 애플의 자체 Core ML입니다.
00:02:16애플의 온디바이스 머신러닝 프레임워크죠.
00:02:19모델을 애플 형식으로 변환한 다음
00:02:23시스템에 넘겨 알아서 처리하도록 하는 방식입니다.
00:02:26하지만 이 방법이 모든 모델에서 잘 통하는 것은 아닙니다.
00:02:28Falcon H1이 바로 그런 모델 중 하나인데요.
00:02:31아키텍처의 절반이 어텐션 레이어를 사용하지 않기 때문입니다.
00:02:35Falcon의 작동 방식은 일반적인 어텐션과 함께
00:02:39모든 레이어에서 Mamba 2라는 상태 공간 모델을 동시에 실행합니다.
00:02:44고정 크기의 메모리 조각 하나를 유지하면서 토큰을 하나씩 처리할 때마다 업데이트하죠.
00:02:49새로운 토큰이 들어올 때마다 무엇을 유지하고 무엇을 덮어쓸지 결정합니다.
00:02:54그리고 이러한 업데이트 시퀀스를 스캔이라고 부릅니다.
00:02:57각 단계가 이전 단계에 의존하기 때문에
00:03:00반드시 순서대로 실행되어야 합니다.
00:03:02나중에 쓰려고 캐시되거나 저장되는 것도 없는데,
00:03:04모두 저 상태로 압축되기 때문입니다.
00:03:07따라서 어텐션보다 정밀도는 떨어지지만
00:03:09메모리 효율이 매우 뛰어납니다.
00:03:11토큰이 1천 개가 쌓여도
00:03:13첫 번째 토큰 때와 정확히 똑같은 양의 메모리를 사용합니다.
00:03:17Falcon은 이 두 가지를 동시에 실행합니다.
00:03:20어텐션 레이어와 맘바 레이어를 함께 돌리죠.
00:03:22그런 다음 그 결과를 더하는데,
00:03:24이게 소형 기기에는 아주 좋습니다.
00:03:26문제는 Core ML에 상태 공간 빌딩 블록이 없다는 점입니다.
00:03:31오직 어텐션 레이어 변환 방법만 알고 있기 때문에
00:03:33맘바 레이어가 변환될 대상이 아예 존재하지 않는 겁니다.
00:03:37더 깊은 문제는 Core ML이 사전에 정의된 고정된 그래프를 원한다는 것인데,
00:03:42스캔은 대화 길이에 따라 길이가 달라지는 루프라는 점입니다.
00:03:47따라서 고정된 길이로 풀어내어 컨텍스트 크기를 고정하거나,
00:03:51아니면 상태를 직접 관리해야 합니다.
00:03:53상태를 직접 관리하는 방법도
00:03:55대화 파이프라인에 통과시키는 방식인데,
00:03:58완벽하게 변환되는 것처럼 실패하다가
00:04:00결국 미묘하게 잘못된 숫자를 뱉어내게 됩니다.
00:04:03결국 Core ML은 우리의 특수한 케이스에 맞지 않지만,
00:04:06우리가 사용할 수 있는 또 다른 선택지가 있습니다.
00:04:08바로 Llama CPP죠.
00:04:10하지만 이것도 그 나름의 문제가 있습니다.
00:04:13macOS, iOS, tvOS, visionOS용
00:04:16빌드 스크립트는 포함되어 있지만,
00:04:19watchOS는 그 목록에 없습니다.
00:04:22그렇다고 프로젝트 어디에도 애플 워치를 지원하지 않는다고 적혀 있는 것은 아니며,
00:04:26웹상에도 이 특정 유스케이스에 대한 정보가 많지 않기 때문에
00:04:31직접 테스트해 보고 Llama CPP를 watchOS에서 실제로 작동시킬 수 있는지 확인해 보기로 했습니다.
00:04:37다행히도 실제로 작동하더군요.
00:04:39필요한 것은 몇 가지 빌드 플래그와 소스 코드 내 한 줄의 가드뿐이었습니다.
00:04:45여기서 혼란이 발생하는 지점이 있습니다.
00:04:47모두가 여기서의 걸림돌이 아키텍처라고 가정하죠.
00:04:50watchOS는 표준 ARM64를 사용하지 않습니다.
00:04:54ARM6432라는 것을 사용합니다.
00:04:57이름만 들으면 왠지 32비트로 축소된 절반 속도의 ARM 변종을 사용하는 것처럼 들리지만,
00:05:05실제로는 그렇지 않습니다.
00:05:06명령어 세트가 완전히 온전하게 유지되어 있으며,
00:05:10그냥 완전한 풀 64비트 ARM이기 때문입니다.
00:05:13Neon을 포함해 아무것도 제거되지 않았습니다.
00:05:15Neon은 수학 연산을 일괄 처리할 수 있게 해주는 ARM의 벡터 유닛이죠.
00:05:19따라서 실제 연산 성능은 다른 ARM 칩과 정확히 똑같이 빠릅니다.
00:05:26다만 유일하게 다른 점은 칩이 메모리를 참조하는 방식입니다.
00:05:30메모리의 모든 위치에는 주소가 있는데, 이는 사실상 숫자일 뿐이며
00:05:35일반적인 64비트 시스템에서는 그 숫자의 길이가 64비트입니다.
00:05:40하지만 워치에서는 단 32비트뿐입니다.
00:05:42애플이 이렇게 한 이유는 워치에는 애초에 1기가바이트의 램밖에 없기 때문입니다.
00:05:47따라서 이러한 주소들의 크기를 줄임으로써 시스템 전체의 메모리를 확보하는 것이죠.
00:05:53하지만 작은 숫자는 셀 수 있는 한계가 있기 때문에 이는 엄격한 제약으로 작용합니다.
00:05:5932비트로는 약 2기가바이트까지만 지정할 수 있으며, 그게 끝입니다.
00:06:03워치는 물리적으로 그 이상의 메모리를 주소 지정할 수 없습니다.
00:06:06즉, 얼마나 공격적으로 양자화하든 대형 모델은 절대 실행할 수 없다는 뜻입니다.
00:06:12하지만 Falcon은 겨우 57메가바이트이므로 한참 여유가 있습니다.
00:06:16하지만 애플 워치에 다른 더 큰 AI 모델을 배포하고 싶다면 이 점을 반드시 명심해야 합니다.
00:06:22다행인 점은 이 과정에서 무엇을 포팅하거나 바꿀 필요가 전혀 없다는 것입니다.
00:06:27Arm 6432는 컴파일러에 빌드하도록 지시하는 타겟일 뿐입니다.
00:06:32그저 다른 플래그를 전달하기만 하면 됩니다.
00:06:34따라서 watchOS용으로 Llama CPP를 올바르게 컴파일하려면 이 명령어를 사용해야 합니다.
00:06:40하지만 우리가 다룰 워치 앱 프로젝트에서는 이미 컴파일되어 있습니다.
00:06:44직접 클론해서 실행해 볼 수 있는 GitHub 저장소 링크를 아래 더보기란에 남겨두겠습니다.
00:06:50그리고 Xcode에서 보시다시피 프로젝트는 꽤 단순합니다.
00:06:54원하는 모델의 다양한 GGUF 파일을 가져올 수 있는 models 폴더가 있을 뿐이죠.
00:07:00다만 매우 작은 웨어러블 기기이므로
00:07:03수십억 개의 파라미터를 가진 모델은 성공적으로 실행할 수 없다는 점을 유념하세요.
00:07:09하지만 이번 특정 데모를 위해 두 개의 AI 모델을 추가해 두었습니다.
00:07:12하나는 앞에서 언급한 9천만 파라미터의 Falcon H1이고요.
00:07:18동일한 작업 세트에서 성능을 비교해 보기 위해 1억 3천 5백만 파라미터의 약간 더 큰 small M2 모델도 추가했습니다.
00:07:27그리고 tools 섹션에는 이 앱을 위해 추가한 부가적인 툴들을 확인할 수 있는 tools samples 파일도 있습니다.
00:07:36이 파일의 이름을 tools로 바꾸기만 하면 특정 툴 호출들이 즉시 등록됩니다.
00:07:41또한 이 파일을 수정하여 프로젝트에 필요한 다른 특정 툴들을 추가하거나 제거할 수도 있습니다.
00:07:48좋습니다.
00:07:49그럼 어떻게 작동하는지 살펴보죠.
00:07:51좋습니다.
00:07:51앱을 열어보겠습니다.
00:07:53여기서 프롬프트를 보낼 모델을 선택할 수 있습니다.
00:07:56먼저 Falcon H1으로 시도해 보죠.
00:07:59이 버튼을 누르고 말을 시작하면 됩니다.
00:08:02프랑스의 수도는 어디인가요?
00:08:05말이 끝나면 완료를 누르고 물어보기 버튼을 누르면 됩니다.
00:08:11보시다시피 위키피디아 툴 호출을 사용하고 있죠.
00:08:14프랑스의 수도는 파리라는 정답을 거의 즉시 대답해 줍니다.
00:08:20초당 24토큰의 속도로 처리해 냈네요.
00:08:24이번에는 소형 모델로 똑같이 시도해 보겠습니다.
00:08:27똑같은 질문을 해볼 수 있죠.
00:08:29다시 위키피디아를 사용합니다.
00:08:31이 모델은 더 큰 모델이라서 그런지 초당 14토큰으로 약간 더 느렸습니다.
00:08:37예상했던 결과죠.
00:08:39날씨 툴 호출도 추가해 보았습니다.
00:08:42현재 기온은 얼마인가요?
00:08:44한번 물어보죠.
00:08:45보시다시피 날씨 툴 콜을 사용하고 있고
00:08:48현재 기온은 섭씨 14.5도라고 나옵니다.
00:08:52이 툴 콜의 경우 위치를 오타와로 하드코딩해 두었다는 점을 말씀드려야겠네요.
00:08:58이 앱에 위치 권한을 추가하고 싶지 않았기 때문입니다.
00:09:02하지만 여러분이 직접 애플리케이션에 적용하신다면 하드코딩하는 대신 현재
00:09:07위치를 참조하도록 설정하는 것이 좋겠죠.
00:09:09이제 좀 더 어려운 질문을 던져 보겠습니다.
00:09:11너비 우선 탐색... 아니 깊이 우선 탐색 알고리즘에 대해 설명해 줄 수 있나요?
00:09:17와우.
00:09:17거의 즉시 답변을 내놓았습니다.
00:09:20그리고 저것 좀 보세요.
00:09:21스트리밍이 엄청나게 빠릅니다.
00:09:23그리고 답변이 길어질수록 점점 느려지는데, 워치가 버틸 수 있는 메모리의 한계에
00:09:29다다르고 있기 때문인 것 같습니다.
00:09:32초당 20토큰 정도로 시작했다가 지금은 10토큰 정도로 떨어진 것 같네요.
00:09:39네, 초당 토큰 수가 어떻게 떨어지는지 눈으로 확인할 수 있습니다.
00:09:42따라서 매우 긴 답변이나 여러 문단의 설명이 필요한 어려운 질문에는 이상적이지 않을 수 있습니다.
00:09:50설명이 많이 필요한 질문에는 말이죠.
00:09:52보시다시피 두 모델 모두 상세한 응답이 필요한 질문에 무리 없이 답변하며
00:09:58이처럼 작은 웨어러블 기기 치고는 비교적 빠른 속도로 작업을 수행하고 있습니다.
00:10:05그래서 이번 결과가 정말 마음에 듭니다.
00:10:08자, 이렇게 해서 완성되었습니다.
00:10:09이제 작동하는 인퍼런스 애플리케이션을 갖추게 되었습니다.
00:10:12이는 애플 워치 시리즈 6처럼 2020년에 나온 오래된 기기조차도 AI 모델을 로컬에서 구동할 만큼
00:10:19충분히 강력하다는 것을 의미합니다.
00:10:21애플은 최근 새로운 시리즈 12 워치를 선보였습니다.
00:10:25일부 가벼운 AI 작업을 수행할 수 있는 온디바이스 뉴럴 엔진이 탑재되어 있긴 하지만,
00:10:32애플이 여전히 기기에서 자유롭게 프롬프트를 입력할 수 있는 범용 로컬 모델을 탑재하지 않은 것은
00:10:38의외입니다.
00:10:39제가 방금 진행한 테스트와 유사한 실험들을 보면 업계는 이미 LLM을 로컬에서 실행할 수 있는
00:10:44역량을 갖춘 충분히 안정적인 단계에 도달했다고 생각합니다.
00:10:49그래서 제 솔직한 의문은 왜 기기 제조사들이 여전히 온에지 LLM으로의 전환을 주저하느냐는 것입니다.
00:10:55LLM 말이죠.
00:10:56여러분은 이 점에 대해 어떻게 생각하시나요?
00:10:58여러분의 생각을 아래 댓글 창에 남겨주세요.
00:11:01그리고 여러분, 이러한 기술적 분석 내용이 마음에 드신다면 영상 아래의
00:11:05좋아요 버튼을 꾹 눌러주시고 채널 구독도 잊지 마세요.
00:11:10지금까지 BetterStack의 안드레스였습니다. 다음 영상에서 뵙겠습니다.
00:11:25안녕히 계세요.
00:11:26안녕히 계세요.
00:11:26안녕히 계세요.
00:11:26안녕히 계세요.
00:11:26안녕히 계세요.
00:11:26안녕히 계세요.
00:11:26안녕히 계세요.
00:11:27안녕히 계세요.

핵심 요약

6년 된 애플 워치 시리즈 6에서도 Llama CPP를 활용하면 9천만 파라미터 규모의 Falcon H1 모델을 오프라인으로 초당 15토큰 속도에 실행할 수 있다.

하이라이트

  • 2020년에 출시된 6년 된 애플 워치 시리즈 6에서 클라우드 스트리밍 없이 완전히 오프라인으로 9천만 개 파라미터의 Falcon H1 AI 모델이 구동된다.

  • 애플 워치 시리즈 6은 초당 평균 약 15토큰의 텍스트를 스트리밍하며, 1세대 라즈베리 파이보다 50배 이상 빠른 성능을 보여준다.

  • 애플의 Core ML은 상태 공간 모델인 맘바 레이어와 가변 길이 루프 구조를 지원하지 않아 LLM 구동에 한계가 있다.

  • Llama CPP는 watchOS를 기본 지원하지 않지만, 소스 코드 내 한 줄의 가드와 몇 가지 빌드 플래그를 추가하면 watchOS에서 정상적으로 작동한다.

  • watchOS는 완전한 풀 64비트 ARM 명령어 세트와 Neon 벡터 유닛을 유지하면서 메모리 주소 지정만 32비트로 제한하는 ARM6432 아키텍처를 사용한다.

  • ARM6432 아키텍처의 32비트 메모리 주소 지정 한계로 인해 약 2GB 이상의 대형 모델은 실행할 수 없다.

타임라인

애플 워치에서의 오프라인 LLM 구동 개요

  • 애플 워치 시리즈 6에서 9천만 개 파라미터의 Falcon H1 모델이 오프라인으로 실행된다.
  • 클라우드 스트리밍 없이 초당 평균 약 15토큰의 속도로 텍스트를 처리한다.
  • 모델의 크기가 작아 놀라운 성능을 내며 툴 호출과 음성 입력을 지원한다.

클라우드 연결 없이 6년 된 웨어러블 기기에서 인공지능 모델을 구동하는 실험이다. 9천만 개 파라미터를 가진 Falcon H1 모델을 백그라운드에서 실행하여 효율적인 성능을 이끌어낸다. 워치 자체의 음성 입력 기능을 결합해 프롬프트 입력과 툴 호출을 원활하게 수행한다.

라즈베리 파이와의 성능 비교 및 Core ML의 한계

  • 애플 워치 시리즈 6은 1세대 라즈베리 파이보다 50배 이상 빠른 추론 속도를 기록한다.
  • 애플의 Core ML 프레임워크는 어텐션 레이어만 변환할 수 있어 맘바 레이어가 포함된 Falcon 모델을 처리하지 못한다.
  • Core ML은 사전에 정의된 고정된 그래프를 요구하지만 맘바의 스캔 과정은 대화 길이에 따라 변하는 루프 형태이다.

과거 1세대 라즈베리 파이에서 초당 0.3토큰으로 버벅이던 모델을 1.8GHz 듀얼 코어와 1GB 램을 탑재한 애플 워치에 적용했을 때의 성능 차이를 비교한다. 애플의 기본 머신러닝 프레임워크인 Core ML을 사용하려 시도했으나, 어텐션과 맘바 레이어가 결합된 하이브리드 아키텍처와 가변 길이 스캔 구조를 지원하지 않는 문제에 부딪힌다.

Llama CPP를 활용한 watchOS 컴파일과 ARM6432 아키텍처

  • Llama CPP는 기본 빌드 목록에 watchOS가 없지만 몇 가지 빌드 플래그와 코드 수정으로 구동할 수 있다.
  • watchOS는 명령어 세트와 Neon 벡터 유닛이 온전한 64비트 ARM 성능을 내는 ARM6432를 사용한다.
  • 메모리 주소 지정 방식만 32비트로 제한되어 있어 최대 약 2GB 이상의 대형 모델은 실행이 불가능하다.

Core ML의 대안으로 Llama CPP를 watchOS에 적용하는 방법을 다룬다. watchOS가 사용하는 ARM6432 아키텍처는 이름과 달리 연산 성능이 깎인 32비트가 아니라 풀 64비트 연산과 네온 유닛을 그대로 지원한다. 단지 메모리 주소 지정이 32비트로 제한되어 2GB 이상의 거대 모델을 올릴 수 없지만, 57MB 크기의 Falcon 모델에는 충분한 여유를 제공한다.

애플 워치 LLM 앱 실기기 데모 및 성능 평가

  • Falcon H1 모델과 1억 3천 5백만 파라미터의 small M2 모델이 앱 내에 추가되어 있다.
  • 위키피디아 조회와 하드코딩된 위치 기반 날씨 조회 같은 툴 호출이 정상적으로 작동한다.
  • 답변이 길어질수록 워치의 메모리 한계로 인해 초당 토큰 처리 속도가 점차 떨어진다.

실제 애플 워치 앱 환경에서 모델을 선택해 질문을 던지고 응답을 받는 과정을 시연한다. 프랑스 수도나 알고리즘에 대한 질문에 위키피디아 툴과 연동하여 즉각적으로 답변을 출력한다. 다만, 답변의 길이가 길어지면 메모리 제약으로 인해 초당 토큰 수가 20개에서 10개 수준으로 감소하는 양상을 보인다.

커뮤니티 글

아직 글이 없습니다. 이 영상에 대한 첫 번째 글을 작성해 보세요!

이 영상에 대해 글쓰기