
MLC LLM을 이용한 안드로이드 On-device AI 맛보기
AI 기술이 급속도로 발전하면서 이제는 클라우드뿐만 아니라 모바일 기기에서도 인공지능 모델을 직접 구동할 수 있는 시대가 되었습니다.특히, 대형 언어 모델(LLM)을 경량화하여 스마트폰에서 직접 실행할 수 있다면 네트워크 연결 없이도 AI 기능을 활용할 수 있고, 개인정보 보호 측면에서도 큰 장점이 있습니다.이 글은 AI 분야에 깊은 지식이 없더라도, 안드로이드 디바이스에서 LLM을 직접 구동해보며 AI를 경험해보고 싶은 소프트웨어 개발자들을 위해 작성되었습니다.제목에 소개된 MLC LLM은 다양한 플랫폼에서 LLM을 효율적으로 실행할 수 있게 해주는 오픈소스 프로젝트로,이를 활용하면 복잡한 AI 지식 없이도 모바일 환경에서 대화형 AI 애플리케이션을 구현할 수 있습니다.MLC LLM을 사용하기 위해서는 Python 환경이 필요합니다. 그리고 추가로 안드로이드 라이브러리화하는 과정에서 Python뿐만 아니라 여러 가지 도구들이 함께 사용됩니다.이 글에 설명된 설치 가이드는 x86_64 기반의 Ubuntu 22.04 (jammy) 환경에서 테스트되었습니다.Python 3.11 버전과 Rust를 설치합니다. Python 패키지를 독립된 환경에서 사용하기 위해 도 같이 설치합니다.를 사용하여 MLC LLM 작업을 위한 독립된 Python 환경을 생성합니다.다음으로, Android 개발 환경을 설치합니다. Android Studio 자체는 MLC LLM을 빌드하는 데 필요는 없지만, 차후 IDE를 이용한 앱 개발을 진행한다고 가정하고 같이 설치해 줍니다.sdkmanager를 사용하기 위해 환경 변수를 설정합니다.이제 를 사용하여 추가로 필요한 패키지를 설치합니다.환경변수에 cmake와 ndk 정보를 추가합니다.이렇게 해서 기본적인 준비 과정을 완료했습니다.MLC LLM은 친절하게 미리 빌드된 패키지(Prebuilt package)를 제공하고 있어 명령으로 쉽게 설치할 수 있습니다.물론, 필요할 경우 소스를 통한 빌드도 함께 제공합니다. 자세한 내용은 공식 문서를 참고 바랍니다.설치가 정상적으로 완료되면 아래와 같이 명령을 터미널에서 사용할 수 있습니다.에서 제공하는 명령으로 독립된 mlc python 환경을 종료합니다.이제 모든 준비 과정이 끝났습니다. 다음 단계에서 MLC LLM을 Android 라이브러리로 빌드하는 과정을 알아보겠습니다.MLC LLM은 두 가지 안드로이드 샘플 앱을 제공합니다. MLCChat과 MLCEngineExample 각각의 빌드 방법을 알아보겠습니다.먼저 코드를 다운로드 받습니다.샘플 코드는 디렉토리에서 찾을 수 있습니다.앱 빌드를 위한 사전 단계로 라는 명령을 사용하게 되는데, 이 때 추가로 필요로 하는 모듈들이 있어 아래와 같이 명령으로 의존성 모듈들을 같이 준비합니다.또한, 추가로 설정이 필요한 환경변수가 있어 마지막으로 아래와 같이 설정합니다.참고로 지금까지 추가된 환경변수들을 정리하면 아래와 같습니다. 쉘 설정 파일( )에 추가하면 좀 더 편리하게 사용할 수 있습니다.빌드 환경 설정이 모두 완료되었습니다. 이제 예제 애플리케이션을 빌드하여 테스트해 보겠습니다. 전체적인 진행 과정은 아래 그림과 같습니다.두 애플리케이션 모두 기본적인 설정 및 빌드 과정은 유사하지만, MLCEngineExample의 경우 최소화된 기능만 제공하므로 몇 가지 작업을 수동으로 추가해야 합니다.그리고 Hugging Face의 mlc-ai 저장소에서 제공하는 모델을 사용할 경우 큰 수정 없이 진행할 수 있으나, 다른 모델을 사용하려면 별도의 변환 과정이 필요합니다.다음 단계에서 이 과정을 더 자세히 살펴보겠습니다.MLCChat (경로: )은 모델 다운로드 기능이 포함된 채팅 형태의 애플리케이션입니다.사용하고 있는 모델 목록은 파일에 아래와 같이 정의되어 있습니다.명령을 수행하면, 위 파일의 에 정의된 각 모델을 다운로드 후 이를 기반으로 안드로이드 앱 빌드를 위한 라이브러리를 생성합니다.따라서, 앱에서 사용할 모델 정보 변경이 필요할 경우 위 json 파일을 수정하고 다시 명령을 실행해야 합니다.모델 다운로드와 TVM Unity 컴파일 과정이 시작되며, 이 과정은 다소 시간이 걸릴 수 있습니다. 작업 진행중 다음과 같은 로그가 출력됩니다.모델에 대한 작업이 끝나면 아래와 같이 로그가 출력됩니다.이후 와 Android NDK를 이용한 빌드가 진행됩니다.MLC LLM 준비가 모두 끝났습니다. 이제 을 이용해 안드로이드 애플리케이션을 빌드합니다.설치 후 실행하면 아래와 같이 모델 목록 화면이 나타나는데, 테스트를 원하는 모델을 찾아 다운로드 버튼을 선택하면 모델 다운로드가 진행됩니다.일부 대형 모델의 경우 스마트폰 메모리 부족으로 다운로드 후 채팅을 시작할 때 앱이 강제 종료될 수 있으니 유의해야 합니다.참고로, Gemma2-2B 모델의 경우 Galaxy S23 기기에서 정상적으로 동작했습니다.Gemma2-2B 모델의 다운로드가 완료된 후 채팅 아이콘을 선택하면 모델 로딩이 시작됩니다.모델에 따라 로딩 시간이 오래 걸릴 수 있습니다. 로딩이 완료되면, 아래와 같이 'Ready to chat' 메시지가 표시됩니다.이제 챗봇 사용자 인터페이스를 이용해서 질문을 입력하고 AI 응답을 받을 수 있습니다."What is the capital of France?" 라고 입력하니 "The capital of France is Paris." 라고 잘 답변하는 것을 확인할 수 있습니다.MLCEngineExample은 MLCChat과 달리 UI 중심의 앱이 아니라 MLCEngine API를 보여주는 코드 중심의 예제 애플리케이션입니다.앱을 실행하면 미리 정의된 프롬프트에 대한 응답을 생성합니다. 빌드 과정은 MLCChat과 동일한데, 모델 사용 방식이 조금 다릅니다.코드에서 모델을 직접 명시한 후, 앱을 빌드하고 apk를 설치한 뒤 명령으로 모델 파일을 안드로이드 디바이스에 수동으로 복사해야 합니다.명령이 정상적으로 완료되면, MLCChat과 다르게 소스코드 수정 과정이 추가로 필요합니다.위 로그 정보에서 얻은 값을 파일에 반영합니다.이후 안드로이드 앱 빌드 과정은 동일합니다.MLCEngi
python
5/2/2025

MLC LLM을 이용한 안드로이드 On-device AI 맛보기
AI 기술이 급속도로 발전하면서 이제는 클라우드뿐만 아니라 모바일 기기에서도 인공지능 모델을 직접 구동할 수 있는 시대가 되었습니다.특히, 대형 언어 모델(LLM)을 경량화하여 스마트폰에서 직접 실행할 수 있다면 네트워크 연결 없이도 AI 기능을 활용할 수 있고, 개인정보 보호 측면에서도 큰 장점이 있습니다.이 글은 AI 분야에 깊은 지식이 없더라도, 안드로이드 디바이스에서 LLM을 직접 구동해보며 AI를 경험해보고 싶은 소프트웨어 개발자들을 위해 작성되었습니다.제목에 소개된 MLC LLM은 다양한 플랫폼에서 LLM을 효율적으로 실행할 수 있게 해주는 오픈소스 프로젝트로,이를 활용하면 복잡한 AI 지식 없이도 모바일 환경에서 대화형 AI 애플리케이션을 구현할 수 있습니다.MLC LLM을 사용하기 위해서는 Python 환경이 필요합니다. 그리고 추가로 안드로이드 라이브러리화하는 과정에서 Python뿐만 아니라 여러 가지 도구들이 함께 사용됩니다.이 글에 설명된 설치 가이드는 x86_64 기반의 Ubuntu 22.04 (jammy) 환경에서 테스트되었습니다.Python 3.11 버전과 Rust를 설치합니다. Python 패키지를 독립된 환경에서 사용하기 위해 도 같이 설치합니다.를 사용하여 MLC LLM 작업을 위한 독립된 Python 환경을 생성합니다.다음으로, Android 개발 환경을 설치합니다. Android Studio 자체는 MLC LLM을 빌드하는 데 필요는 없지만, 차후 IDE를 이용한 앱 개발을 진행한다고 가정하고 같이 설치해 줍니다.sdkmanager를 사용하기 위해 환경 변수를 설정합니다.이제 를 사용하여 추가로 필요한 패키지를 설치합니다.환경변수에 cmake와 ndk 정보를 추가합니다.이렇게 해서 기본적인 준비 과정을 완료했습니다.MLC LLM은 친절하게 미리 빌드된 패키지(Prebuilt package)를 제공하고 있어 명령으로 쉽게 설치할 수 있습니다.물론, 필요할 경우 소스를 통한 빌드도 함께 제공합니다. 자세한 내용은 공식 문서를 참고 바랍니다.설치가 정상적으로 완료되면 아래와 같이 명령을 터미널에서 사용할 수 있습니다.에서 제공하는 명령으로 독립된 mlc python 환경을 종료합니다.이제 모든 준비 과정이 끝났습니다. 다음 단계에서 MLC LLM을 Android 라이브러리로 빌드하는 과정을 알아보겠습니다.MLC LLM은 두 가지 안드로이드 샘플 앱을 제공합니다. MLCChat과 MLCEngineExample 각각의 빌드 방법을 알아보겠습니다.먼저 코드를 다운로드 받습니다.샘플 코드는 디렉토리에서 찾을 수 있습니다.앱 빌드를 위한 사전 단계로 라는 명령을 사용하게 되는데, 이 때 추가로 필요로 하는 모듈들이 있어 아래와 같이 명령으로 의존성 모듈들을 같이 준비합니다.또한, 추가로 설정이 필요한 환경변수가 있어 마지막으로 아래와 같이 설정합니다.참고로 지금까지 추가된 환경변수들을 정리하면 아래와 같습니다. 쉘 설정 파일( )에 추가하면 좀 더 편리하게 사용할 수 있습니다.빌드 환경 설정이 모두 완료되었습니다. 이제 예제 애플리케이션을 빌드하여 테스트해 보겠습니다. 전체적인 진행 과정은 아래 그림과 같습니다.두 애플리케이션 모두 기본적인 설정 및 빌드 과정은 유사하지만, MLCEngineExample의 경우 최소화된 기능만 제공하므로 몇 가지 작업을 수동으로 추가해야 합니다.그리고 Hugging Face의 mlc-ai 저장소에서 제공하는 모델을 사용할 경우 큰 수정 없이 진행할 수 있으나, 다른 모델을 사용하려면 별도의 변환 과정이 필요합니다.다음 단계에서 이 과정을 더 자세히 살펴보겠습니다.MLCChat (경로: )은 모델 다운로드 기능이 포함된 채팅 형태의 애플리케이션입니다.사용하고 있는 모델 목록은 파일에 아래와 같이 정의되어 있습니다.명령을 수행하면, 위 파일의 에 정의된 각 모델을 다운로드 후 이를 기반으로 안드로이드 앱 빌드를 위한 라이브러리를 생성합니다.따라서, 앱에서 사용할 모델 정보 변경이 필요할 경우 위 json 파일을 수정하고 다시 명령을 실행해야 합니다.모델 다운로드와 TVM Unity 컴파일 과정이 시작되며, 이 과정은 다소 시간이 걸릴 수 있습니다. 작업 진행중 다음과 같은 로그가 출력됩니다.모델에 대한 작업이 끝나면 아래와 같이 로그가 출력됩니다.이후 와 Android NDK를 이용한 빌드가 진행됩니다.MLC LLM 준비가 모두 끝났습니다. 이제 을 이용해 안드로이드 애플리케이션을 빌드합니다.설치 후 실행하면 아래와 같이 모델 목록 화면이 나타나는데, 테스트를 원하는 모델을 찾아 다운로드 버튼을 선택하면 모델 다운로드가 진행됩니다.일부 대형 모델의 경우 스마트폰 메모리 부족으로 다운로드 후 채팅을 시작할 때 앱이 강제 종료될 수 있으니 유의해야 합니다.참고로, Gemma2-2B 모델의 경우 Galaxy S23 기기에서 정상적으로 동작했습니다.Gemma2-2B 모델의 다운로드가 완료된 후 채팅 아이콘을 선택하면 모델 로딩이 시작됩니다.모델에 따라 로딩 시간이 오래 걸릴 수 있습니다. 로딩이 완료되면, 아래와 같이 'Ready to chat' 메시지가 표시됩니다.이제 챗봇 사용자 인터페이스를 이용해서 질문을 입력하고 AI 응답을 받을 수 있습니다."What is the capital of France?" 라고 입력하니 "The capital of France is Paris." 라고 잘 답변하는 것을 확인할 수 있습니다.MLCEngineExample은 MLCChat과 달리 UI 중심의 앱이 아니라 MLCEngine API를 보여주는 코드 중심의 예제 애플리케이션입니다.앱을 실행하면 미리 정의된 프롬프트에 대한 응답을 생성합니다. 빌드 과정은 MLCChat과 동일한데, 모델 사용 방식이 조금 다릅니다.코드에서 모델을 직접 명시한 후, 앱을 빌드하고 apk를 설치한 뒤 명령으로 모델 파일을 안드로이드 디바이스에 수동으로 복사해야 합니다.명령이 정상적으로 완료되면, MLCChat과 다르게 소스코드 수정 과정이 추가로 필요합니다.위 로그 정보에서 얻은 값을 파일에 반영합니다.이후 안드로이드 앱 빌드 과정은 동일합니다.MLCEngi
2025.05.02
python

좋아요

별로에요

OpenStack VM 전원 동기화 로직 분석
OpenStack 에서 Nova API 를 호출하여 명시적으로 전원을 종료하지 않고 VM 내에서 전원을 종료한다거나 VM Crash 등으로 전원 상태가 바뀌면 Nova 에서 이를 어떻게 감지하고 DB 에 동기화할까?내부 로직을 살펴보고 이해할 수 있도록 정리하고자 합니다.분석 환경은 다음과 같습니다.위 Workflow 는 큰 흐름을 이해하기 위한 다이어그램입니다. (아래 내부 로직에서 더 자세히 설명)• None nova-compute 서비스가 구동되면 libvirt 에 연결하여 VM event 를 폴링• None VM 전원 상태가 변경되면 이벤트를 감지하고 이를 event queue 에 적재• None 이벤트를 적재했다는 알림을 Pipe 를 통해 전달• None 이벤트를 디스패치하여 ComputeManager 로 이벤트를 내보냄• None ComputeManager 는 변경된 전원 상태를 DB 에 업데이트nova 는 libvirt-python 라이브러리를 이용해 Libvirt 의 domain lifecycle 이벤트를 수신하도록 구현되어 있습니다.nova-compute 가 구동되면 libvirt driver 가 초기화되면서 libvirtd 에 연결할 때 domainEventRegisterAny() 로 이벤트 리스너를 등록하여 VM 이벤트를 수신할 수 있게 됩니다.• None 11 라인에서 domainEventRegisterAny() 를 이용해 이벤트 리스너를 등록• None libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE : 이벤트 ID 기반 lifecycle 이벤트만 수신 한다는 의미테스트를 위해 테스트 코드를 작성하였습니다.• None libvirt 에 이벤트 리스너를 등록하고 이벤트 감지 시 event_lifecycle_callback() 콜백함수를 실행하는 코드입니다.• None event_lifecycle_callback() 콜백함수는 이벤트 ID 와 Detail 이벤트 ID 를 출력합니다.테스트 코드를 실행하고 VM 을 종료/시작 해보았습니다.• None shutdown 시 이벤트 ID 6번과 Detail ID 1번을 수신합니다.• None shutdown 시 이벤트 ID 5번과 Detail ID 0번을 수신합니다.• None start 시 이벤트 ID 4번과 Detail ID 0 번을 수신합니다.• None start 시 이벤트 ID 2번과 Detail ID 0 번을 수신합니다.이벤트 ID 와 Detail ID 의 의미는 libvirt.py 라이브러리 내의 상수로 정의되어 있습니다.• None 위 의미를 기반으로 shutdown 시 전달된 두 개의 이벤트를 해석해 보면 다음과 같습니다.• None• None VM 종료가 완료되었다는 의미다음으로 이벤트 감지 후 실행되는 콜백 함수에 대해 살펴보겠습니다.• None 위에서 살펴본 libvirt 의 이벤트와 Detail 이벤트를 nova 의 virtevnet 와 매핑하여 transition 을 정의 한 다음• None 49 라인에서 _queue_event() 를 호출하여 이벤트를 큐에 보내게 됩니다.nova 의 virtevent 는 다음과 같이 정의됩니다.다음으로 콜백 함수에서 _queue_event() 를 통해 큐로 전달된 이벤트가 어떻게 처리되는지 이어서 살펴보겠습니다.우선 이벤트를 담을 큐는 초기화 시 다음과 같이 생성됩니다.• None 8 라인에서 event queue 는 native_Queue.Queue() 객체를 이용해 생성됩니다.• None native_Queue 는 python 내장 queue 모듈이며, 큐의 데이터를 관리• None 추가로 11,12 라인에서 _event_notify_send() 및 recv() 함수를 정의합니다.• None 역할은 큐에 데이터가 적재되면 적재되었다고 리시버에게 알리는 역할• None os.pipe() 로 리눅스 운영체제의 파이프를 이용하며, python eventlet 의 greenio.GreenPipe() 를 이용해 비동기로 알람을 보냄• None wb 와 rb 의 차이는 wb 는 write 권한 및 binary 모드로 파이프를 open 하는 의미이고,• None rb 는 read 및 binary 모드로 파이프를 open 하는 의미다시 돌아와 콜백함수에서 이벤트 전달 시 사용한 _queue_event() 를 살펴보겠습니다.• None 13 라인에서 _event_queue.put() 으로 이벤트를 큐에 적재• None 이후 16 ~ 18 라인에서 공백 문자(' ') 를 바이트로 encode() 후 _event_notify_send.write() 로 파이프를 통해 큐에 데이터가 적재되었다는 알람을 보냄• None flush 는 버퍼를 플러쉬하는 함수인데, 버퍼가 있으면 알람이 안갈 수 있어 즉시 플러쉬다음으로 큐에 적재된 이벤트를 어떻게 가져와 처리하는지 살펴보겠습니다.이벤트가 큐에 적재되었다는 알림이 보내지면 이를 디스패치 스레드가 감지하게 되어있습니다.위 디스패치 스레드가 무한 루프 돌리는 _dispatch_events() 는 큐에서 이벤트를 꺼내 내보내는 역할을 합니다.• None 11 라인에서 파이프에서 1바이트를 읽어 신호가 왔음을 감지• None 22 라인에서 큐에서 이벤트를 하나씩 꺼냄• None 27 라인에서 InstanceEvent 인 이벤트이면 _event_emit_delayed() 메서드를 호출하여 이벤트를 내보냄다음으로 위에서 살펴본 디스패치 이벤트에서 이벤트를 내보낼 때 사용한 _event_emit_delayed() 메서드를 살펴보겠습니다._event_emit_delayed() 는 이벤트를 ComputeManager 로 내보내는 역할을 합니다.• None Instacne 이벤트가 STOPPED 이면 일정시간 딜레이 후 처리하게 되어있음 (17라인)• None 이유는 재부팅인 VM 인 경우 곧바로 start 가 올 수 있어 딜레이를 줌• None 그 외 이벤트는 28 라인에서 _event_emit() 메서드를 호출하여 이벤트를 내보내게 됩니다.• None _event_emit 는 _lifecycle_event_handle
5/2/2025

OpenStack VM 전원 동기화 로직 분석
OpenStack 에서 Nova API 를 호출하여 명시적으로 전원을 종료하지 않고 VM 내에서 전원을 종료한다거나 VM Crash 등으로 전원 상태가 바뀌면 Nova 에서 이를 어떻게 감지하고 DB 에 동기화할까?내부 로직을 살펴보고 이해할 수 있도록 정리하고자 합니다.분석 환경은 다음과 같습니다.위 Workflow 는 큰 흐름을 이해하기 위한 다이어그램입니다. (아래 내부 로직에서 더 자세히 설명)• None nova-compute 서비스가 구동되면 libvirt 에 연결하여 VM event 를 폴링• None VM 전원 상태가 변경되면 이벤트를 감지하고 이를 event queue 에 적재• None 이벤트를 적재했다는 알림을 Pipe 를 통해 전달• None 이벤트를 디스패치하여 ComputeManager 로 이벤트를 내보냄• None ComputeManager 는 변경된 전원 상태를 DB 에 업데이트nova 는 libvirt-python 라이브러리를 이용해 Libvirt 의 domain lifecycle 이벤트를 수신하도록 구현되어 있습니다.nova-compute 가 구동되면 libvirt driver 가 초기화되면서 libvirtd 에 연결할 때 domainEventRegisterAny() 로 이벤트 리스너를 등록하여 VM 이벤트를 수신할 수 있게 됩니다.• None 11 라인에서 domainEventRegisterAny() 를 이용해 이벤트 리스너를 등록• None libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE : 이벤트 ID 기반 lifecycle 이벤트만 수신 한다는 의미테스트를 위해 테스트 코드를 작성하였습니다.• None libvirt 에 이벤트 리스너를 등록하고 이벤트 감지 시 event_lifecycle_callback() 콜백함수를 실행하는 코드입니다.• None event_lifecycle_callback() 콜백함수는 이벤트 ID 와 Detail 이벤트 ID 를 출력합니다.테스트 코드를 실행하고 VM 을 종료/시작 해보았습니다.• None shutdown 시 이벤트 ID 6번과 Detail ID 1번을 수신합니다.• None shutdown 시 이벤트 ID 5번과 Detail ID 0번을 수신합니다.• None start 시 이벤트 ID 4번과 Detail ID 0 번을 수신합니다.• None start 시 이벤트 ID 2번과 Detail ID 0 번을 수신합니다.이벤트 ID 와 Detail ID 의 의미는 libvirt.py 라이브러리 내의 상수로 정의되어 있습니다.• None 위 의미를 기반으로 shutdown 시 전달된 두 개의 이벤트를 해석해 보면 다음과 같습니다.• None• None VM 종료가 완료되었다는 의미다음으로 이벤트 감지 후 실행되는 콜백 함수에 대해 살펴보겠습니다.• None 위에서 살펴본 libvirt 의 이벤트와 Detail 이벤트를 nova 의 virtevnet 와 매핑하여 transition 을 정의 한 다음• None 49 라인에서 _queue_event() 를 호출하여 이벤트를 큐에 보내게 됩니다.nova 의 virtevent 는 다음과 같이 정의됩니다.다음으로 콜백 함수에서 _queue_event() 를 통해 큐로 전달된 이벤트가 어떻게 처리되는지 이어서 살펴보겠습니다.우선 이벤트를 담을 큐는 초기화 시 다음과 같이 생성됩니다.• None 8 라인에서 event queue 는 native_Queue.Queue() 객체를 이용해 생성됩니다.• None native_Queue 는 python 내장 queue 모듈이며, 큐의 데이터를 관리• None 추가로 11,12 라인에서 _event_notify_send() 및 recv() 함수를 정의합니다.• None 역할은 큐에 데이터가 적재되면 적재되었다고 리시버에게 알리는 역할• None os.pipe() 로 리눅스 운영체제의 파이프를 이용하며, python eventlet 의 greenio.GreenPipe() 를 이용해 비동기로 알람을 보냄• None wb 와 rb 의 차이는 wb 는 write 권한 및 binary 모드로 파이프를 open 하는 의미이고,• None rb 는 read 및 binary 모드로 파이프를 open 하는 의미다시 돌아와 콜백함수에서 이벤트 전달 시 사용한 _queue_event() 를 살펴보겠습니다.• None 13 라인에서 _event_queue.put() 으로 이벤트를 큐에 적재• None 이후 16 ~ 18 라인에서 공백 문자(' ') 를 바이트로 encode() 후 _event_notify_send.write() 로 파이프를 통해 큐에 데이터가 적재되었다는 알람을 보냄• None flush 는 버퍼를 플러쉬하는 함수인데, 버퍼가 있으면 알람이 안갈 수 있어 즉시 플러쉬다음으로 큐에 적재된 이벤트를 어떻게 가져와 처리하는지 살펴보겠습니다.이벤트가 큐에 적재되었다는 알림이 보내지면 이를 디스패치 스레드가 감지하게 되어있습니다.위 디스패치 스레드가 무한 루프 돌리는 _dispatch_events() 는 큐에서 이벤트를 꺼내 내보내는 역할을 합니다.• None 11 라인에서 파이프에서 1바이트를 읽어 신호가 왔음을 감지• None 22 라인에서 큐에서 이벤트를 하나씩 꺼냄• None 27 라인에서 InstanceEvent 인 이벤트이면 _event_emit_delayed() 메서드를 호출하여 이벤트를 내보냄다음으로 위에서 살펴본 디스패치 이벤트에서 이벤트를 내보낼 때 사용한 _event_emit_delayed() 메서드를 살펴보겠습니다._event_emit_delayed() 는 이벤트를 ComputeManager 로 내보내는 역할을 합니다.• None Instacne 이벤트가 STOPPED 이면 일정시간 딜레이 후 처리하게 되어있음 (17라인)• None 이유는 재부팅인 VM 인 경우 곧바로 start 가 올 수 있어 딜레이를 줌• None 그 외 이벤트는 28 라인에서 _event_emit() 메서드를 호출하여 이벤트를 내보내게 됩니다.• None _event_emit 는 _lifecycle_event_handle
2025.05.02

좋아요

별로에요

MCP 개념 및 LINE Messaging API를 활용한 MCP 서버 구축 사례 소개
최근 Anthropic에서 Claude LLM을 통해 모델 컨텍스트 프로토콜(Model Context Protocol, 이하 MCP)을 발표했습니다. MCP는 대형 언어 모델(large language model, 이하 LLM)이 외부 데이터 소스나 기능을 사용할 수 있도록 돕는 프로토콜로, Anthropic 에서 누구나 사용할 수 있는 오픈 프로토콜로 공개했습니다(참고). 이에 따라 많은 서비스에서 MCP를 지원하기 시작했고, 많은 사용자가 MCP를 사용해 LLM과 외부 서비스를 연결하는 방법에 관심을 갖기 시작했습니다.이번 글에서는 많은 관심을 받고 있는 MCP의 개념과 아키텍처를 설명하고, LINE Messaging API를 활용해 MCP 서버를 구현하는 방법을 소개하겠습니다.MCP는 LLM이 외부 기능을 사용할 수 있도록 지원하는 프로토콜입니다. 아래는 LLM만 단독으로 사용하는 경우와 MCP를 활용한 경우를 비교한 그림입니다.예를 들어 LINE의 오픈소스 라이브러리인 Armeria에서 특정 코드를 검색하고 싶을 때 LLM 애플리케이션에 프롬프트를 작성해 요청하면, LLM 애플리케이션은 실제 GitHub에 접속해서 Armeria 라이브러리를 조사하는 것이 아니라 기존에 학습한 모델을 바탕으로 응답할 것입니다. AI 할루시네이션이 발생할 수 있는 상황이죠.반면 GitHub MCP를 사용하면 LLM 애플리케이션이 GitHub에 접속해 실제 Armeria 리포지터리에서 해당 코드를 검색한 뒤 검색 결과를 기준으로 응답합니다. 다만 이를 위해서는 외부 서비스인 GitHub에서 MCP 서버를 제공해야 하며, 사용하는 LLM 애플리케이션에서도 이 MCP를 사용해 호출해야 하는데요. 이와 같이 LLM 애플리케이션에서 외부 기능을 사용할 수 있도록 정의한 프로토콜을 MCP라고 합니다(참고로 GitHub은 실제로 GitHub MCP를 제공하고 있습니다).MCP는 기본적으로 호스트의 클라이언트가 서버와 연결되는 클라이언트-서버 아키텍처를 따릅니다.이 아키텍처는 호스트, 클라이언트, 서버, 이 세 가지 주체로 구성되며, 각 주체의 역할은 다음과 같습니다.• 호스트: MCP를 사용하는 주체인 LLM 애플리케이션을 가리키며, 사용자의 요청을 받아 응답하는 애플리케이션입니다. 이후 예제에서 'Claude 데스크톱 애플리케이션'이 호스트에 해당합니다.• 클라이언트: 호스트의 내부 모듈로 MCP 서버에 요청을 전송한 뒤 응답을 받아 호스트에게 전달합니다.• 서버: 호스트 외부에 존재하며 MCP 클라이언트로부터 받은 요청을 처리하고 응답하는 애플리케이션입니다.MCP 호스트가 사용할 수 있는 요소는 다양합니다. 그중 가장 핵심적인 요소인 툴과 리소스를 소개하겠습니다.툴(tools)은 MCP의 핵심 요소로 외부 기능을 실행할 수 있도록 MCP 서버가 제공하는 요소입니다. MCP 서버는 실행할 수 있는 툴 목록을 확인할 수 있는 엔드포인트인 와, 원하는 툴을 호출할 수 있는 엔드포인트인 를 제공합니다. MCP 호스트는 사용자 프롬프트에 대한 응답을 처리하는 과정에서 외부 기능 호출이 필요한 경우 MCP 클라이언트를 통해 MCP 서버가 제공하는 툴을 사용합니다.예를 들어 GitHub MCP 서버에서는 라는 툴을 제공하며, 사용자는 프롬프트를 통해 이 툴을 이용해 새로운 PR을 만들 수 있습니다.리소스(resources) 역시 MCP의 핵심 요소로, MCP 서버가 제공할 수 있는 다양한 형태의 데이터나 콘텐츠를 의미합니다. 리소스는 파일 내용이나 데이터베이스 레코드, API 응답 등 다양한 형태로 존재할 수 있습니다. MCP 클라이언트는 MCP 서버에 사용할 수 있는 리소스 목록을 요청해 받은 뒤, 다시 필요한 리소스를 요청해서 데이터를 가져올 수 있습니다. MCP 클라이언트가 가져온 데이터는 MCP 호스트로 전달되며, MCP 호스트는 이 데이터를 사용자의 프롬프트 응답에 활용할 수 있습니다.예를 들어 GitHub MCP 서버에서는 API 리소스를 통해 특정 리포지터리의 소스 코드를 제공합니다.MCP는 어떻게 구현하느냐에 따라서 다양한 방식으로 작동할 수 있는데요. 이 글에서는 아래 그림과 함께 가장 기초적인 방식을 알아보겠습니다.• MCP 호스트가 실행될 때 MCP 클라이언트를 통해 MCP 서버의 엔드포인트를 호출해 사용 가능한 툴 목록을 받아옵니다.• 사용자가 MCP 호스트에게 프롬프트를 보냅니다.• MCP 호스트는 사용자의 프롬프트와 사전에 받아온 툴 목록을 LLM 모델로 전달합니다. LLM 모델은 툴 목록 중 사용이 필요하다고 판단된 툴들을 사용하겠다고 응답합니다.• MCP 호스트는 MCP 클라이언트를 통해 MCP 서버의 엔드포인트로 해당 툴 사용을 요청합니다.• MCP 호스트는 MCP 서버의 툴 응답과 기존 사용자의 프롬프트를 다시 LLM 모델로 전달하고, LLM 모델은 이를 기반으로 최종 응답을 생성합니다.• MCP 호스트는 LLM 모델로부터 받은 최종 응답을 가공해 사용자에게 전달합니다.LINE Messaging API와 함께 하는 MCP 활용 사례이제 LINE의 Messaging API를 활용해 MCP를 직접 사용해 보겠습니다. LINE은 LINE 공식 계정(Official Account, OA)을 위한 Messaging API를 제공하고 있으며, 이를 통해 공식 계정을 친구로 등록한 사용자에게 메시지를 보내는 등의 행동을 할 수 있는데요. 이를 활용해 MCP 서버를 구축해 보겠습니다. MCP 공식 사용자 가이드의 For Server Developers 문서와 LINE Developers 사이트의 Messaging API 문서를 함께 참고하시면 좋을 것 같습니다.LINE Messaging API를 활용해 MCP 서버를 구축하기 위해서는 다음 준비가 필요합니다.• LINE Messaging API 사용 준비• LINE Developers의 Get started with the Messaging API 문서를 참고해 공식 계정 생성 후 Messaging API 활성화해 채널 생성• LINE Developer Console에 접속해 앞서 생성한 채널의 Messaging API 탭 하단에서 채
github
5/2/2025

MCP 개념 및 LINE Messaging API를 활용한 MCP 서버 구축 사례 소개
최근 Anthropic에서 Claude LLM을 통해 모델 컨텍스트 프로토콜(Model Context Protocol, 이하 MCP)을 발표했습니다. MCP는 대형 언어 모델(large language model, 이하 LLM)이 외부 데이터 소스나 기능을 사용할 수 있도록 돕는 프로토콜로, Anthropic 에서 누구나 사용할 수 있는 오픈 프로토콜로 공개했습니다(참고). 이에 따라 많은 서비스에서 MCP를 지원하기 시작했고, 많은 사용자가 MCP를 사용해 LLM과 외부 서비스를 연결하는 방법에 관심을 갖기 시작했습니다.이번 글에서는 많은 관심을 받고 있는 MCP의 개념과 아키텍처를 설명하고, LINE Messaging API를 활용해 MCP 서버를 구현하는 방법을 소개하겠습니다.MCP는 LLM이 외부 기능을 사용할 수 있도록 지원하는 프로토콜입니다. 아래는 LLM만 단독으로 사용하는 경우와 MCP를 활용한 경우를 비교한 그림입니다.예를 들어 LINE의 오픈소스 라이브러리인 Armeria에서 특정 코드를 검색하고 싶을 때 LLM 애플리케이션에 프롬프트를 작성해 요청하면, LLM 애플리케이션은 실제 GitHub에 접속해서 Armeria 라이브러리를 조사하는 것이 아니라 기존에 학습한 모델을 바탕으로 응답할 것입니다. AI 할루시네이션이 발생할 수 있는 상황이죠.반면 GitHub MCP를 사용하면 LLM 애플리케이션이 GitHub에 접속해 실제 Armeria 리포지터리에서 해당 코드를 검색한 뒤 검색 결과를 기준으로 응답합니다. 다만 이를 위해서는 외부 서비스인 GitHub에서 MCP 서버를 제공해야 하며, 사용하는 LLM 애플리케이션에서도 이 MCP를 사용해 호출해야 하는데요. 이와 같이 LLM 애플리케이션에서 외부 기능을 사용할 수 있도록 정의한 프로토콜을 MCP라고 합니다(참고로 GitHub은 실제로 GitHub MCP를 제공하고 있습니다).MCP는 기본적으로 호스트의 클라이언트가 서버와 연결되는 클라이언트-서버 아키텍처를 따릅니다.이 아키텍처는 호스트, 클라이언트, 서버, 이 세 가지 주체로 구성되며, 각 주체의 역할은 다음과 같습니다.• 호스트: MCP를 사용하는 주체인 LLM 애플리케이션을 가리키며, 사용자의 요청을 받아 응답하는 애플리케이션입니다. 이후 예제에서 'Claude 데스크톱 애플리케이션'이 호스트에 해당합니다.• 클라이언트: 호스트의 내부 모듈로 MCP 서버에 요청을 전송한 뒤 응답을 받아 호스트에게 전달합니다.• 서버: 호스트 외부에 존재하며 MCP 클라이언트로부터 받은 요청을 처리하고 응답하는 애플리케이션입니다.MCP 호스트가 사용할 수 있는 요소는 다양합니다. 그중 가장 핵심적인 요소인 툴과 리소스를 소개하겠습니다.툴(tools)은 MCP의 핵심 요소로 외부 기능을 실행할 수 있도록 MCP 서버가 제공하는 요소입니다. MCP 서버는 실행할 수 있는 툴 목록을 확인할 수 있는 엔드포인트인 와, 원하는 툴을 호출할 수 있는 엔드포인트인 를 제공합니다. MCP 호스트는 사용자 프롬프트에 대한 응답을 처리하는 과정에서 외부 기능 호출이 필요한 경우 MCP 클라이언트를 통해 MCP 서버가 제공하는 툴을 사용합니다.예를 들어 GitHub MCP 서버에서는 라는 툴을 제공하며, 사용자는 프롬프트를 통해 이 툴을 이용해 새로운 PR을 만들 수 있습니다.리소스(resources) 역시 MCP의 핵심 요소로, MCP 서버가 제공할 수 있는 다양한 형태의 데이터나 콘텐츠를 의미합니다. 리소스는 파일 내용이나 데이터베이스 레코드, API 응답 등 다양한 형태로 존재할 수 있습니다. MCP 클라이언트는 MCP 서버에 사용할 수 있는 리소스 목록을 요청해 받은 뒤, 다시 필요한 리소스를 요청해서 데이터를 가져올 수 있습니다. MCP 클라이언트가 가져온 데이터는 MCP 호스트로 전달되며, MCP 호스트는 이 데이터를 사용자의 프롬프트 응답에 활용할 수 있습니다.예를 들어 GitHub MCP 서버에서는 API 리소스를 통해 특정 리포지터리의 소스 코드를 제공합니다.MCP는 어떻게 구현하느냐에 따라서 다양한 방식으로 작동할 수 있는데요. 이 글에서는 아래 그림과 함께 가장 기초적인 방식을 알아보겠습니다.• MCP 호스트가 실행될 때 MCP 클라이언트를 통해 MCP 서버의 엔드포인트를 호출해 사용 가능한 툴 목록을 받아옵니다.• 사용자가 MCP 호스트에게 프롬프트를 보냅니다.• MCP 호스트는 사용자의 프롬프트와 사전에 받아온 툴 목록을 LLM 모델로 전달합니다. LLM 모델은 툴 목록 중 사용이 필요하다고 판단된 툴들을 사용하겠다고 응답합니다.• MCP 호스트는 MCP 클라이언트를 통해 MCP 서버의 엔드포인트로 해당 툴 사용을 요청합니다.• MCP 호스트는 MCP 서버의 툴 응답과 기존 사용자의 프롬프트를 다시 LLM 모델로 전달하고, LLM 모델은 이를 기반으로 최종 응답을 생성합니다.• MCP 호스트는 LLM 모델로부터 받은 최종 응답을 가공해 사용자에게 전달합니다.LINE Messaging API와 함께 하는 MCP 활용 사례이제 LINE의 Messaging API를 활용해 MCP를 직접 사용해 보겠습니다. LINE은 LINE 공식 계정(Official Account, OA)을 위한 Messaging API를 제공하고 있으며, 이를 통해 공식 계정을 친구로 등록한 사용자에게 메시지를 보내는 등의 행동을 할 수 있는데요. 이를 활용해 MCP 서버를 구축해 보겠습니다. MCP 공식 사용자 가이드의 For Server Developers 문서와 LINE Developers 사이트의 Messaging API 문서를 함께 참고하시면 좋을 것 같습니다.LINE Messaging API를 활용해 MCP 서버를 구축하기 위해서는 다음 준비가 필요합니다.• LINE Messaging API 사용 준비• LINE Developers의 Get started with the Messaging API 문서를 참고해 공식 계정 생성 후 Messaging API 활성화해 채널 생성• LINE Developer Console에 접속해 앞서 생성한 채널의 Messaging API 탭 하단에서 채
2025.05.02
github

좋아요

별로에요

NPU: AI 효율을 극대화하는 전용 프로세서
인공지능(AI) 기술이 비약적으로 발전하면서, 대량의 연산을 빠르게 처리할 수 있는 전용 하드웨어의 필요성이 대두되었습니다. 기존의 CPU와 GPU가 범용성과 병렬 처리에 강점을 보였지만, AI 특히 딥러닝 모델의 추론(inference) 작업에서는 한계가 있었습니다. 이러한 상황에서 등장한 것이 바로 Neural Processing Unit(NPU) 입니다. 이번 글에서는 NPU의 개념과 등장 배경, CPU 및 GPU와의 차이, 장단점을 분석하고, 특히 로보틱스 분야에서 NPU가 제공하는 혁신적 가능성에 대해 다루겠습니다.NPUNPU는 인공 신경망 연산에 최적화된 전용 프로세서로, 대규모 행렬 연산과 병렬 처리를 통해 AI 모델의 추론 속도를 크게 향상시킵니다. 기존의 CPU는 범용 처리를, GPU는 그래픽 및 대량의 병렬 연산을 처리하는 데 특화되어 있는 반면, NPU는 딥러닝 알고리즘의 특징인 곱셈-누적 연산을 매우 효율적으로 수행할 수 있도록 설계되었습니다. 예를 들어, 모바일 기기에서는 NPU 덕분에 얼굴 인식, 음성 명령 처리 등 복잡한 AI 기능을 실시간으로 수행할 수 있게 됐습니다.NPU는 AI 가속기(AI Accelerator), 딥러닝 프로세서(DLP, Deep Learning Processor), 딥러닝 가속기(DLA, Deep Learning Accelerator)와 같이 여러 이름이 있지만, 본 글에서는 NPU로 통일하여 표현하였습니다.CPU, GPU와의 비교그렇다면, 많은 분야에서 널리 사용되는 CPU와 GPU랑 비교하면 NPU는 어떤 차이점을 갖고 있을까요? NPU는 아키텍처 및 병렬성을 바탕으로 CPU, GPU와 차이점이 있어 전력 효율과 성능 측면에서 두각을 드러냅니다. 하지만, CPU 및 GPU와 비교하면 그 역사가 길지 않아 개발 생태계가 충분히 갖추어져 있지 않는 한계도 있습니다.아키텍처 및 병렬성NPU는 AI 최적화를 위해 CPU 및 GPU와 비교하여 다른 구조를 갖고 있다는 점이 가장 중요한 차이점입니다.CPU: 소수의 고성능 코어를 활용해 순차적 작업을 빠르게 처리하지만, 대규모 병렬 처리에는 한계가 있습니다.GPU: 수백에서 수천 개의 코어를 사용해 병렬 연산에 강점을 가지며, 주로 그래픽 처리 및 딥러닝 학습에 적합합니다.NPU: 신경망 연산에 특화된 구조를 도입해, 불필요한 연산을 최소화하고 메모리 접근을 최적화하여 낮은 전력 소모로 높은 연산 성능을 발휘합니다.전력 효율과 성능구조의 차이로 인해 NPU는 AI 처리에 더욱 효율적입니다. CPU와 GPU는 높은 연산 능력을 제공하지만, 특히 GPU는 전력 소모와 발열 문제가 발생할 수 있습니다. 반면 NPU는 필요한 연산만을 전용 회로로 수행하기 때문에 에너지 효율성이 뛰어나며, 로봇을 포함한 배터리 기반의 모바일 기기나 임베디드 시스템에서 실시간 AI 처리를 가능하게 합니다.개발 및 배포 환경CPU와 GPU는 오랜 기간 축적된 성숙한 소프트웨어 생태계를 갖추고 있어 개발자들이 쉽게 활용할 수 있습니다. 그러나 NPU는 제조사마다 지원하는 SDK나 도구가 달라, 개발 및 최적화 과정이 상대적으로 복잡할 수 있습니다. 최신 NPU 제품들은 이러한 문제를 개선하려는 노력이 계속되고 있으므로, 점차 더 나은 개발 환경이 구축되고 있습니다.NPU의 장단점NPU는 AI 연산에 최적화된 구조를 통해 더 빠르면서 효율적으로 연산을 수행하며 실시간성(저지연)을 포함한 여러 장점을 갖고 있습니다. 하지만, 충분히 성숙되지 않은 분야로 점차 완성도를 갖춰나가는 모습을 보이고 있기도 합니다.장점높은 AI 연산 성능: NPU는 인공 신경망 연산에 최적화되어 있어, CPU나 GPU보다 훨씬 빠른 추론 속도를 제공함우수한 전력 효율성: 전용 하드웨어 설계 덕분에 동일한 작업을 처리할 때 소비 전력이 적어, 배터리 구동 기기에서 유리함낮은 지연 시간: 클라우드에 의존하지 않고 기기 내에서 데이터를 처리함으로써, 네트워크 지연이 줄어들어 실시간 응답이 요구되는 애플리케이션에 적합함단점개발 복잡성: 제조사마다 상이한 도구와 SDK로 인해 개발 및 최적화 과정이 까다로울 수 있음범용성 제한: AI 추론에 특화되어 있어, 범용 연산이나 복잡한 제어 로직 처리에는 적합하지 않음비용 문제: 전용 NPU를 설계 및 제조하는 데 추가 비용이 발생할 수 있으며, 시스템 통합 시 호환성 문제도 고려해야 함적용 분야NPU는 이미 다양한 분야에서 활용되고 있으며, AI를 사용하는 다양한 분야에서 응용되고 있습니다. AI 기능에 대한 수요가 많이지면서 AI를 효율적으로 처리하는 NPU에 대한 수요와 관심도 점점 높아지는 추세입니다.모바일 및 IoT 디바이스: 스마트폰, 태블릿, 스마트 스피커 등에서 실시간 이미지 및 음성 인식을 구현함데이터 센터 및 클라우드: AI 추론 작업을 가속하여, 대규모 사용자 요청에 대한 응답 시간을 단축함자율주행 및 첨단 운전자 보조 시스템(ADAS): 센서 데이터를 빠르게 처리해 실시간으로 도로 상황을 판단하고 대응함산업용 및 보안 카메라: 현장에서 실시간으로 데이터를 분석하여, 빠른 대응과 프라이버시 보호를 지원함로보틱스에서의 NPU로보틱스 분야는 NPU의 실시간 데이터 처리 능력과 낮은 전력 소모 덕분에 큰 혜택을 보고 있습니다. 로봇은 주행, 물체 인식, 경로 계획 등 다양한 작업을 수행하는데, NPU가 탑재된 시스템은 다음과 같은 이점을 제공합니다:실시간 컴퓨터 비전: 카메라와 센서를 통해 들어오는 데이터를 즉각 분석하여 장애물을 피하거나 목표물을 식별함에너지 효율성: 배터리로 구동되는 로봇에서 NPU는 전력 소모를 줄여 운용 시간을 늘려 더 오래 서비스가 가능함현장 내 자율 판단: 네트워크 지연 없이 기기 자체에서 데이터 처리 및 판단을 내림으로써, 로봇이 독립적으로 작동하게 함개인정보 보호: 로봇에서 AI에 필요한 데이터를 처리해 민감 정보가 로봇 밖으로 보내지지 않음NPU의 미래AI 기술이 지속적으로 발전함에 따라 NPU의 역할은 더욱 중요해질 것입니다. 향후 NPU는 CPU와 GPU와의 이기종 통합 시스템의 핵심 부품으로 자리잡을 가능성이 높으며, 소형 임베디드 시스템에서도 AI
5/1/2025

NPU: AI 효율을 극대화하는 전용 프로세서
인공지능(AI) 기술이 비약적으로 발전하면서, 대량의 연산을 빠르게 처리할 수 있는 전용 하드웨어의 필요성이 대두되었습니다. 기존의 CPU와 GPU가 범용성과 병렬 처리에 강점을 보였지만, AI 특히 딥러닝 모델의 추론(inference) 작업에서는 한계가 있었습니다. 이러한 상황에서 등장한 것이 바로 Neural Processing Unit(NPU) 입니다. 이번 글에서는 NPU의 개념과 등장 배경, CPU 및 GPU와의 차이, 장단점을 분석하고, 특히 로보틱스 분야에서 NPU가 제공하는 혁신적 가능성에 대해 다루겠습니다.NPUNPU는 인공 신경망 연산에 최적화된 전용 프로세서로, 대규모 행렬 연산과 병렬 처리를 통해 AI 모델의 추론 속도를 크게 향상시킵니다. 기존의 CPU는 범용 처리를, GPU는 그래픽 및 대량의 병렬 연산을 처리하는 데 특화되어 있는 반면, NPU는 딥러닝 알고리즘의 특징인 곱셈-누적 연산을 매우 효율적으로 수행할 수 있도록 설계되었습니다. 예를 들어, 모바일 기기에서는 NPU 덕분에 얼굴 인식, 음성 명령 처리 등 복잡한 AI 기능을 실시간으로 수행할 수 있게 됐습니다.NPU는 AI 가속기(AI Accelerator), 딥러닝 프로세서(DLP, Deep Learning Processor), 딥러닝 가속기(DLA, Deep Learning Accelerator)와 같이 여러 이름이 있지만, 본 글에서는 NPU로 통일하여 표현하였습니다.CPU, GPU와의 비교그렇다면, 많은 분야에서 널리 사용되는 CPU와 GPU랑 비교하면 NPU는 어떤 차이점을 갖고 있을까요? NPU는 아키텍처 및 병렬성을 바탕으로 CPU, GPU와 차이점이 있어 전력 효율과 성능 측면에서 두각을 드러냅니다. 하지만, CPU 및 GPU와 비교하면 그 역사가 길지 않아 개발 생태계가 충분히 갖추어져 있지 않는 한계도 있습니다.아키텍처 및 병렬성NPU는 AI 최적화를 위해 CPU 및 GPU와 비교하여 다른 구조를 갖고 있다는 점이 가장 중요한 차이점입니다.CPU: 소수의 고성능 코어를 활용해 순차적 작업을 빠르게 처리하지만, 대규모 병렬 처리에는 한계가 있습니다.GPU: 수백에서 수천 개의 코어를 사용해 병렬 연산에 강점을 가지며, 주로 그래픽 처리 및 딥러닝 학습에 적합합니다.NPU: 신경망 연산에 특화된 구조를 도입해, 불필요한 연산을 최소화하고 메모리 접근을 최적화하여 낮은 전력 소모로 높은 연산 성능을 발휘합니다.전력 효율과 성능구조의 차이로 인해 NPU는 AI 처리에 더욱 효율적입니다. CPU와 GPU는 높은 연산 능력을 제공하지만, 특히 GPU는 전력 소모와 발열 문제가 발생할 수 있습니다. 반면 NPU는 필요한 연산만을 전용 회로로 수행하기 때문에 에너지 효율성이 뛰어나며, 로봇을 포함한 배터리 기반의 모바일 기기나 임베디드 시스템에서 실시간 AI 처리를 가능하게 합니다.개발 및 배포 환경CPU와 GPU는 오랜 기간 축적된 성숙한 소프트웨어 생태계를 갖추고 있어 개발자들이 쉽게 활용할 수 있습니다. 그러나 NPU는 제조사마다 지원하는 SDK나 도구가 달라, 개발 및 최적화 과정이 상대적으로 복잡할 수 있습니다. 최신 NPU 제품들은 이러한 문제를 개선하려는 노력이 계속되고 있으므로, 점차 더 나은 개발 환경이 구축되고 있습니다.NPU의 장단점NPU는 AI 연산에 최적화된 구조를 통해 더 빠르면서 효율적으로 연산을 수행하며 실시간성(저지연)을 포함한 여러 장점을 갖고 있습니다. 하지만, 충분히 성숙되지 않은 분야로 점차 완성도를 갖춰나가는 모습을 보이고 있기도 합니다.장점높은 AI 연산 성능: NPU는 인공 신경망 연산에 최적화되어 있어, CPU나 GPU보다 훨씬 빠른 추론 속도를 제공함우수한 전력 효율성: 전용 하드웨어 설계 덕분에 동일한 작업을 처리할 때 소비 전력이 적어, 배터리 구동 기기에서 유리함낮은 지연 시간: 클라우드에 의존하지 않고 기기 내에서 데이터를 처리함으로써, 네트워크 지연이 줄어들어 실시간 응답이 요구되는 애플리케이션에 적합함단점개발 복잡성: 제조사마다 상이한 도구와 SDK로 인해 개발 및 최적화 과정이 까다로울 수 있음범용성 제한: AI 추론에 특화되어 있어, 범용 연산이나 복잡한 제어 로직 처리에는 적합하지 않음비용 문제: 전용 NPU를 설계 및 제조하는 데 추가 비용이 발생할 수 있으며, 시스템 통합 시 호환성 문제도 고려해야 함적용 분야NPU는 이미 다양한 분야에서 활용되고 있으며, AI를 사용하는 다양한 분야에서 응용되고 있습니다. AI 기능에 대한 수요가 많이지면서 AI를 효율적으로 처리하는 NPU에 대한 수요와 관심도 점점 높아지는 추세입니다.모바일 및 IoT 디바이스: 스마트폰, 태블릿, 스마트 스피커 등에서 실시간 이미지 및 음성 인식을 구현함데이터 센터 및 클라우드: AI 추론 작업을 가속하여, 대규모 사용자 요청에 대한 응답 시간을 단축함자율주행 및 첨단 운전자 보조 시스템(ADAS): 센서 데이터를 빠르게 처리해 실시간으로 도로 상황을 판단하고 대응함산업용 및 보안 카메라: 현장에서 실시간으로 데이터를 분석하여, 빠른 대응과 프라이버시 보호를 지원함로보틱스에서의 NPU로보틱스 분야는 NPU의 실시간 데이터 처리 능력과 낮은 전력 소모 덕분에 큰 혜택을 보고 있습니다. 로봇은 주행, 물체 인식, 경로 계획 등 다양한 작업을 수행하는데, NPU가 탑재된 시스템은 다음과 같은 이점을 제공합니다:실시간 컴퓨터 비전: 카메라와 센서를 통해 들어오는 데이터를 즉각 분석하여 장애물을 피하거나 목표물을 식별함에너지 효율성: 배터리로 구동되는 로봇에서 NPU는 전력 소모를 줄여 운용 시간을 늘려 더 오래 서비스가 가능함현장 내 자율 판단: 네트워크 지연 없이 기기 자체에서 데이터 처리 및 판단을 내림으로써, 로봇이 독립적으로 작동하게 함개인정보 보호: 로봇에서 AI에 필요한 데이터를 처리해 민감 정보가 로봇 밖으로 보내지지 않음NPU의 미래AI 기술이 지속적으로 발전함에 따라 NPU의 역할은 더욱 중요해질 것입니다. 향후 NPU는 CPU와 GPU와의 이기종 통합 시스템의 핵심 부품으로 자리잡을 가능성이 높으며, 소형 임베디드 시스템에서도 AI
2025.05.01

좋아요

별로에요

Simplicity 4 : AI 아바타가 발표하는 온라인 컨퍼런스 제작기
Simplicity는 더 나은 사용자 경험을 만들기 위해, 토스가 치열하게 고민해온 과정을 나누는 디자인 컨퍼런스예요. 우리의 실험과 시도들이 사용자 경험을 고민하는 다른 디자이너들에게도 영감이 되기를 바라며 시작했어요.2021년부터 토스 디자인 챕터가 정기적으로 개최하고 있죠. 내용뿐 아니라 메시지를 어떻게 전달할지도 늘 중요하게 여겼기 때문에, 2023년부터는 유튜브 영상이 아닌 웹 기반 인터랙티브 사이트로 전환해 운영하고 있어요.디자인 챕터에게 심플리시티는 거의 종합 예술에 가까운 프로젝트예요. 운영, 디자인, 개발, 대본, 촬영, 녹음, 홍보까지—모든 과정이 고도화된 협업으로 이루어지죠.한 번으로 끝나는 행사가 아니라, 매년 반복되는 시즌제 컨퍼런스이기 때문에 ‘지속 가능성’이 정말 중요한 주제였어요. 매년 퀄리티와 지속 가능성 사이의 균형을 고민해야 했죠. 그 과정에서 많은 부분을 효율적으로 만들어왔지만, 촬영만큼은 늘 어려운 과제였어요.촬영을 하려면 대본이 완성되어야 하는데, 그 과정만 무려 두 달이 넘게 걸려요. 내부 피드백, 법무·보안·개인정보 검토를 거치며 수차례 수정되고, 최종적으로는 발표자 톤에 맞춰 구어체로 다시 다듬어야 하거든요. 대본이 늦어지면 촬영도 늦어지고, 전체 일정이 밀리기도 하죠.그런데 이게 끝이 아니에요. 혹여라도 대본상의 문제를 나중에 발견하게 되면, 다시 촬영을 해야 해야 하거든요. 촬영은 디자인 챕터의 전문 영역이 아니라 항상 외부 전문가나 다른 팀의 도움을 받아야 하는 구조적 제약도 있었죠.더 큰 문제는, 발표 경험이 익숙하지 않은 연사들에게도 부담이 컸다는 거예요. 실제로 워크숍에서 연사자들이 가장 꺼리는 일로 “발표하기, 촬영하기, 녹음하기”를 꼽았을 정도였죠. 컨퍼런스인데, 발표가 가장 하기 싫다니—아이러니하죠?그래서 자연스럽게 이런 질문이 생겼어요AI 아바타가 발표한다면그래서 이번 시즌에는 새로운 방식을 시도했어요. AI 아바타가 발표를 대신해보는 실험이었죠. 혹시 눈치채신 분 계실까요?간단할 거라고 생각했지만, 막상 해보니 쉽지만은 않았어요. AI 서비스들의 한국어 지원이 매끄럽지 않아서, 자연스러운 음성을 만들기가 어려웠거든요. 그래서 여러 번 테스트를 거쳐, 최적의 방법을 찾아냈어요.기존의 방식이라면 연사자는 발표 내용을 자연스럽게 말하기 위해 여러 번 연습하고, 촬영 중간에 한 번이라도 말을 더듬거나 버벅이면 처음부터 다시 찍어야 했어요. 하지만 이번에는 딱 한 번만 찍어도 AI 아바타를 만드는 데 충분했어요.촬영 자체도 훨씬 간편해졌어요. AI 아바타 생성을 위한 학습용 데이터로만 쓰이다 보니, 연사자가 회의실에 들어와서 나갈 때까지 30분이면 촬영이 끝났거든요.덕분에 연사자의 부담은 확 줄었고, 일정도 유연하게 조율할 수 있었어요. 심지어 오픈을 일주일 앞두고도 대본 수정이 가능한 정도였죠.촬영은 어떻게 했냐고요? 아마 들으면 깜짝 놀라실 거예요. 스튜디오도, 전문 장비도 없었어요. 회의실에서, 아이폰 전면 카메라로, 스노우 앱을 켜고 녹화했거든요. 말 그대로 셀카 찍듯 촬영했
5/1/2025

Simplicity 4 : AI 아바타가 발표하는 온라인 컨퍼런스 제작기
Simplicity는 더 나은 사용자 경험을 만들기 위해, 토스가 치열하게 고민해온 과정을 나누는 디자인 컨퍼런스예요. 우리의 실험과 시도들이 사용자 경험을 고민하는 다른 디자이너들에게도 영감이 되기를 바라며 시작했어요.2021년부터 토스 디자인 챕터가 정기적으로 개최하고 있죠. 내용뿐 아니라 메시지를 어떻게 전달할지도 늘 중요하게 여겼기 때문에, 2023년부터는 유튜브 영상이 아닌 웹 기반 인터랙티브 사이트로 전환해 운영하고 있어요.디자인 챕터에게 심플리시티는 거의 종합 예술에 가까운 프로젝트예요. 운영, 디자인, 개발, 대본, 촬영, 녹음, 홍보까지—모든 과정이 고도화된 협업으로 이루어지죠.한 번으로 끝나는 행사가 아니라, 매년 반복되는 시즌제 컨퍼런스이기 때문에 ‘지속 가능성’이 정말 중요한 주제였어요. 매년 퀄리티와 지속 가능성 사이의 균형을 고민해야 했죠. 그 과정에서 많은 부분을 효율적으로 만들어왔지만, 촬영만큼은 늘 어려운 과제였어요.촬영을 하려면 대본이 완성되어야 하는데, 그 과정만 무려 두 달이 넘게 걸려요. 내부 피드백, 법무·보안·개인정보 검토를 거치며 수차례 수정되고, 최종적으로는 발표자 톤에 맞춰 구어체로 다시 다듬어야 하거든요. 대본이 늦어지면 촬영도 늦어지고, 전체 일정이 밀리기도 하죠.그런데 이게 끝이 아니에요. 혹여라도 대본상의 문제를 나중에 발견하게 되면, 다시 촬영을 해야 해야 하거든요. 촬영은 디자인 챕터의 전문 영역이 아니라 항상 외부 전문가나 다른 팀의 도움을 받아야 하는 구조적 제약도 있었죠.더 큰 문제는, 발표 경험이 익숙하지 않은 연사들에게도 부담이 컸다는 거예요. 실제로 워크숍에서 연사자들이 가장 꺼리는 일로 “발표하기, 촬영하기, 녹음하기”를 꼽았을 정도였죠. 컨퍼런스인데, 발표가 가장 하기 싫다니—아이러니하죠?그래서 자연스럽게 이런 질문이 생겼어요AI 아바타가 발표한다면그래서 이번 시즌에는 새로운 방식을 시도했어요. AI 아바타가 발표를 대신해보는 실험이었죠. 혹시 눈치채신 분 계실까요?간단할 거라고 생각했지만, 막상 해보니 쉽지만은 않았어요. AI 서비스들의 한국어 지원이 매끄럽지 않아서, 자연스러운 음성을 만들기가 어려웠거든요. 그래서 여러 번 테스트를 거쳐, 최적의 방법을 찾아냈어요.기존의 방식이라면 연사자는 발표 내용을 자연스럽게 말하기 위해 여러 번 연습하고, 촬영 중간에 한 번이라도 말을 더듬거나 버벅이면 처음부터 다시 찍어야 했어요. 하지만 이번에는 딱 한 번만 찍어도 AI 아바타를 만드는 데 충분했어요.촬영 자체도 훨씬 간편해졌어요. AI 아바타 생성을 위한 학습용 데이터로만 쓰이다 보니, 연사자가 회의실에 들어와서 나갈 때까지 30분이면 촬영이 끝났거든요.덕분에 연사자의 부담은 확 줄었고, 일정도 유연하게 조율할 수 있었어요. 심지어 오픈을 일주일 앞두고도 대본 수정이 가능한 정도였죠.촬영은 어떻게 했냐고요? 아마 들으면 깜짝 놀라실 거예요. 스튜디오도, 전문 장비도 없었어요. 회의실에서, 아이폰 전면 카메라로, 스노우 앱을 켜고 녹화했거든요. 말 그대로 셀카 찍듯 촬영했
2025.05.01

좋아요

별로에요

AI 아바타가 발표한 Simplicity 4 제작기
Simplicity는 더 나은 사용자 경험을 만들기 위해, 토스가 치열하게 고민해온 과정을 나누는 디자인 컨퍼런스예요. 우리의 실험과 시도들이 사용자 경험을 고민하는 다른 디자이너들에게도 영감이 되기를 바라며 시작했어요.2021년부터 토스 디자인 챕터가 정기적으로 개최하고 있죠. 내용뿐 아니라 메시지를 어떻게 전달할지도 늘 중요하게 여겼기 때문에, 2023년부터는 유튜브 영상이 아닌 웹 기반 인터랙티브 사이트로 전환해 운영하고 있어요.디자인 챕터에게 심플리시티는 거의 종합 예술에 가까운 프로젝트예요. 운영, 디자인, 개발, 대본, 촬영, 녹음, 홍보까지—모든 과정이 고도화된 협업으로 이루어지죠.한 번으로 끝나는 행사가 아니라, 매년 반복되는 시즌제 컨퍼런스이기 때문에 ‘지속 가능성’이 정말 중요한 주제였어요. 매년 퀄리티와 지속 가능성 사이의 균형을 고민해야 했죠. 그 과정에서 많은 부분을 효율적으로 만들어왔지만, 촬영만큼은 늘 어려운 과제였어요.촬영을 하려면 대본이 완성되어야 하는데, 그 과정만 무려 두 달이 넘게 걸려요. 내부 피드백, 법무·보안·개인정보 검토를 거치며 수차례 수정되고, 최종적으로는 발표자 톤에 맞춰 구어체로 다시 다듬어야 하거든요. 대본이 늦어지면 촬영도 늦어지고, 전체 일정이 밀리기도 하죠.그런데 이게 끝이 아니에요. 혹여라도 대본상의 문제를 나중에 발견하게 되면, 다시 촬영을 해야 해야 하거든요. 촬영은 디자인 챕터의 전문 영역이 아니라 항상 외부 전문가나 다른 팀의 도움을 받아야 하는 구조적 제약도 있었죠.더 큰 문제는, 발표 경험이 익숙하지 않은 연사들에게도 부담이 컸다는 거예요. 실제로 워크숍에서 연사자들이 가장 꺼리는 일로 “발표하기, 촬영하기, 녹음하기”를 꼽았을 정도였죠. 컨퍼런스인데, 발표가 가장 하기 싫다니—아이러니하죠?그래서 자연스럽게 이런 질문이 생겼어요:AI 아바타가 발표한다면그래서 이번 시즌에는 새로운 방식을 시도했어요. AI 아바타가 발표를 대신해보는 실험이었죠. 혹시 눈치채신 분 계실까요?간단할 거라고 생각했지만, 막상 해보니 쉽지만은 않았어요. AI 서비스들의 한국어 지원이 매끄럽지 않아서, 자연스러운 음성을 만들기가 어려웠거든요. 그래서 여러 번 테스트를 거쳐, 최적의 방법을 찾아냈어요.기존의 방식이라면 연사자는 발표 내용을 자연스럽게 말하기 위해 여러 번 연습하고, 촬영 중간에 한 번이라도 말을 더듬거나 버벅이면 처음부터 다시 찍어야 했어요. 하지만 이번에는 딱 한 번만 찍어도 AI 아바타를 만드는 데 충분했어요.촬영 자체도 훨씬 간편해졌어요. AI 아바타 생성을 위한 학습용 데이터로만 쓰이다 보니, 연사자가 회의실에 들어와서 나갈 때까지 30분이면 촬영이 끝났거든요.덕분에 연사자의 부담은 확 줄었고, 일정도 유연하게 조율할 수 있었어요. 심지어 오픈을 일주일 앞두고도 대본 수정이 가능한 정도였죠.촬영은 어떻게 했냐고요? 아마 들으면 깜짝 놀라실 거예요. 스튜디오도, 전문 장비도 없었어요. 회의실에서, 아이폰 전면 카메라로, 스노우 앱을 켜고 녹화했거든요. 말 그대로 셀카 찍듯 촬영
5/1/2025

AI 아바타가 발표한 Simplicity 4 제작기
Simplicity는 더 나은 사용자 경험을 만들기 위해, 토스가 치열하게 고민해온 과정을 나누는 디자인 컨퍼런스예요. 우리의 실험과 시도들이 사용자 경험을 고민하는 다른 디자이너들에게도 영감이 되기를 바라며 시작했어요.2021년부터 토스 디자인 챕터가 정기적으로 개최하고 있죠. 내용뿐 아니라 메시지를 어떻게 전달할지도 늘 중요하게 여겼기 때문에, 2023년부터는 유튜브 영상이 아닌 웹 기반 인터랙티브 사이트로 전환해 운영하고 있어요.디자인 챕터에게 심플리시티는 거의 종합 예술에 가까운 프로젝트예요. 운영, 디자인, 개발, 대본, 촬영, 녹음, 홍보까지—모든 과정이 고도화된 협업으로 이루어지죠.한 번으로 끝나는 행사가 아니라, 매년 반복되는 시즌제 컨퍼런스이기 때문에 ‘지속 가능성’이 정말 중요한 주제였어요. 매년 퀄리티와 지속 가능성 사이의 균형을 고민해야 했죠. 그 과정에서 많은 부분을 효율적으로 만들어왔지만, 촬영만큼은 늘 어려운 과제였어요.촬영을 하려면 대본이 완성되어야 하는데, 그 과정만 무려 두 달이 넘게 걸려요. 내부 피드백, 법무·보안·개인정보 검토를 거치며 수차례 수정되고, 최종적으로는 발표자 톤에 맞춰 구어체로 다시 다듬어야 하거든요. 대본이 늦어지면 촬영도 늦어지고, 전체 일정이 밀리기도 하죠.그런데 이게 끝이 아니에요. 혹여라도 대본상의 문제를 나중에 발견하게 되면, 다시 촬영을 해야 해야 하거든요. 촬영은 디자인 챕터의 전문 영역이 아니라 항상 외부 전문가나 다른 팀의 도움을 받아야 하는 구조적 제약도 있었죠.더 큰 문제는, 발표 경험이 익숙하지 않은 연사들에게도 부담이 컸다는 거예요. 실제로 워크숍에서 연사자들이 가장 꺼리는 일로 “발표하기, 촬영하기, 녹음하기”를 꼽았을 정도였죠. 컨퍼런스인데, 발표가 가장 하기 싫다니—아이러니하죠?그래서 자연스럽게 이런 질문이 생겼어요:AI 아바타가 발표한다면그래서 이번 시즌에는 새로운 방식을 시도했어요. AI 아바타가 발표를 대신해보는 실험이었죠. 혹시 눈치채신 분 계실까요?간단할 거라고 생각했지만, 막상 해보니 쉽지만은 않았어요. AI 서비스들의 한국어 지원이 매끄럽지 않아서, 자연스러운 음성을 만들기가 어려웠거든요. 그래서 여러 번 테스트를 거쳐, 최적의 방법을 찾아냈어요.기존의 방식이라면 연사자는 발표 내용을 자연스럽게 말하기 위해 여러 번 연습하고, 촬영 중간에 한 번이라도 말을 더듬거나 버벅이면 처음부터 다시 찍어야 했어요. 하지만 이번에는 딱 한 번만 찍어도 AI 아바타를 만드는 데 충분했어요.촬영 자체도 훨씬 간편해졌어요. AI 아바타 생성을 위한 학습용 데이터로만 쓰이다 보니, 연사자가 회의실에 들어와서 나갈 때까지 30분이면 촬영이 끝났거든요.덕분에 연사자의 부담은 확 줄었고, 일정도 유연하게 조율할 수 있었어요. 심지어 오픈을 일주일 앞두고도 대본 수정이 가능한 정도였죠.촬영은 어떻게 했냐고요? 아마 들으면 깜짝 놀라실 거예요. 스튜디오도, 전문 장비도 없었어요. 회의실에서, 아이폰 전면 카메라로, 스노우 앱을 켜고 녹화했거든요. 말 그대로 셀카 찍듯 촬영
2025.05.01

좋아요

별로에요

이미지와 음성을 아우르는 카카오의 멀티모달 언어모델 Kanana-o 알아보기
안녕하세요, 카카오의 AI 모델 개발을 담당하는 카나나(Kanana) 조직의 Edwin(강우영), James(이재명) 입니다. 저희 팀에서는 다양한 모달리티 데이터를 처리할 수 있는 멀티모달 언어모델을 중점적으로 개발하고 있습니다.지난해 12월, 이미지를 이해할 수 있는 멀티모달 언어모델인 Kanana-v를 소개해 드린 바 있는데요. 이번 글에서는 텍스트와 오디오를 이해하는 오디오 언어모델인 Kanana-a와 텍스트, 이미지, 오디오 모두를 이해하는 Kanana-o를 소개합니다.Kanana-o는 Kanana-v와 Kanana-a를 모델 병합(Model Merging) 기법으로 결합하여 학습 효율을 극대화했습니다. 또한, 자체 제작한 이미지-오디오 통합 모달리티 데이터를 포함해 지금까지 쌓아온 학습 노하우를 바탕으로, 단기간에 다양한 한국어 및 영어 벤치마크에서 글로벌 경쟁력을 입증했습니다.이번 글에서는 이러한 결과를 만들어내기까지 저희가 마주했던 도전 과제들과, 이를 극복하기 위해 고민하고 노력했던 과정을 자세히 소개하고자 합니다.그림 2. Kanana-o와 글로벌 경쟁모델들의 음성 및 통합 모달리티 벤치마크 성능 비교특히, 아직 소개해드리지 못헀던 Kanana-a에 대해 먼저 자세하게 소개하고, 이를 Kanana-v와 결합하여 Kanana-o를 만든 과정을 설명드리겠습니다. 이어서 성능에 대한 자세한 정량 수치와 다양한 활용 예시들을 보여드리며 글을 마무리하도록 하겠습니다.사람과 기계가 소통하는 가장 자연스러운 방식은 ‘말하기’라고 할 수 있습니다. 음성은 텍스트보다 입력 속도가 빠르고, 시각적 주의를 요구하지 않으며, 몰입감 있는 소통 수단으로서도 강력합니다. 특히 운전 중, 운동 중, AR/VR 기기처럼 손이나 눈이 자유롭지 않은 환경에서는 텍스트보다 훨씬 직관적인 인터페이스가 됩니다.그뿐만 아니라, 음성은 단순한 정보 전달을 넘어 감정과 뉘앙스까지 담을 수 있는 소통의 수단입니다. 우리는 누군가의 말투, 속도, 억양, 리듬, 배경 소리까지 종합해 의미를 해석하고, 그에 맞는 방식으로 반응합니다.반면, 텍스트 중심 LLM은 이 모든 비 언어적 정보(paralinguistic cues)를 인식하지 못하고 단어 그 자체에만 반응합니다. 예를 들어, 떨리는 목소리로 말하는 “괜찮아요”는 문자로는 표현되지 않는 감정을 담고 있으며, 격앙된 고객의 말투에 맞춰 상담사가 말하는 속도를 낮추는 것도 텍스트만으로는 구현하기 어렵습니다.이처럼 실제 상황에서 사람과 사람 사이의 상호작용은 텍스트로 환원되기 어려운 정보들로 가득 차 있습니다.그래서, Audio LLM은 단순한 텍스트 LLM의 확장이 아니라, 인간과 기계 간 소통 방식을 근본적으로 바꾸는 새로운 패러다임이라고 할 수 있습니다. 이 섹션에서는 저희가 Audio LLM을 설계하며 겪은 기술적 고민과 구조적 선택에 대한 내용을 공유드리고자 합니다.Kanana-a의 개발 과정과 전체 구조Kanana-a는 텍스트와 음성을 함께 이해하고 생성할 수 있는 멀티모달 언어모델로, 전체 구조는 세 가지 주요 모듈로 구성됩니다.첫 번째는 오디오 인코딩(audio encoding) 모듈로, 입력된 음성 신호를 멜 스펙트로그램(Mel Spectrogram)으로 변환한 후, 오디오 인코더를 통해 LLM이 처리 가능한 형태의 임베딩 벡터로 압축합니다.두 번째는 LLM 기반 응답 생성 단계입니다. 이 과정에서 모델은 텍스트와 음성 임베딩을 함께 입력받아, 질의에 대한 의미를 통합적으로 이해하고 적절한 응답 시퀀스를 생성합니다.마지막으로, LLM에서 생성된 응답은 오디오 디코딩(audio decoding) 모듈을 통해 사람이 들을 수 있는 실제 음성 파형으로 복원됩니다. 이 단계에서는 LLM의 응답을 참고하여 이산적인 음성 토큰을 만들어낸 뒤 멜 디코더와 보코더가 함께 사용되어 자연스러운 음성 출력을 완성합니다.그림 3. 음성 이해 언어모델인 Kanana-a의 모델 구조. Voice Token LM으로부터 나오는 이산 음성 토큰을 실제 음성 파형으로 변경해주는 token-to-wav 합성 모듈은 그림에서 생략 되어있음.음성 데이터는 텍스트에 비해 입력 길이와 복잡도가 훨씬 높습니다. 예를 들어, “안녕하세요”와 같은 1초 분량의 인사말을 16kHz로 샘플링하면, 16,000개의 연속적인 숫자로 표현됩니다. 이처럼 단 몇 초의 음성도 수만 개의 숫자로 구성되기 때문에, 이를 그대로 대형 언어모델(LLM)에 입력하면 막대한 연산량과 지연(latency) 문제가 발생하게 됩니다.그렇다면 입력으로 주어지는 원본(raw) 음성 신호를 어떻게 하면 더 짧고 효율적인 형태로 바꿔 입력할 수 있을까요? 이 문제에 대한 저희의 고민과 경험을 바로 이어서 공유드리겠습니다.그림 4. 오디오 인코딩 모듈. 입력으로 들어오는 음성 신호가 mel spectrogram으로의 변환을 거쳐 Audio Encoder와 Audio Projector를 순차적으로 통과하며 LLM의 입력 벡터로 변환 됩니다.오디오 인코더: Raw 음성 신호를 LLM 친화적인 표현으로먼저, 입력된 음성 신호는 오디오 인코더(Audio Encoder)를 통해 일정 수준 압축된 피처 벡터(feature vector)로 변환됩니다. 일반적으로 멀티모달 언어모델에서는 각 모달리티에 대해 사전학습된 인코더(pretrained encoder)를 사용합니다.저희는 음성 인식 분야에서 널리 쓰이고 있는 OpenAI의 Whisper[1] 모델을 채택했습니다. Whisper는 96개 언어, 약 68만 시간 규모의 대규모 데이터를 학습한 모델로, MIT 라이선스 하에 공개되어 있어 제품을 개발하는 기업 입장에서도 접근성이 매우 좋은 모델이라고 할 수 있습니다.Whisper 인코더의 특징 중 하나는 높은 압축률인데요, 예를 들어, 초당 16,000개의 샘플로 구성된 음성 데이터를 멜 스펙트로그램으로 변환한 뒤 Whisper 인코더에 통과시키면, 초당 50개의 특징 벡터들만으로 표현할 수 있습니다.더욱 짧게 압축할 순 없을까? - 추가적인 Audio Projector의 설계Whisper 인코딩만으로도 압축률은 상당하지만, 1분
5/1/2025

이미지와 음성을 아우르는 카카오의 멀티모달 언어모델 Kanana-o 알아보기
안녕하세요, 카카오의 AI 모델 개발을 담당하는 카나나(Kanana) 조직의 Edwin(강우영), James(이재명) 입니다. 저희 팀에서는 다양한 모달리티 데이터를 처리할 수 있는 멀티모달 언어모델을 중점적으로 개발하고 있습니다.지난해 12월, 이미지를 이해할 수 있는 멀티모달 언어모델인 Kanana-v를 소개해 드린 바 있는데요. 이번 글에서는 텍스트와 오디오를 이해하는 오디오 언어모델인 Kanana-a와 텍스트, 이미지, 오디오 모두를 이해하는 Kanana-o를 소개합니다.Kanana-o는 Kanana-v와 Kanana-a를 모델 병합(Model Merging) 기법으로 결합하여 학습 효율을 극대화했습니다. 또한, 자체 제작한 이미지-오디오 통합 모달리티 데이터를 포함해 지금까지 쌓아온 학습 노하우를 바탕으로, 단기간에 다양한 한국어 및 영어 벤치마크에서 글로벌 경쟁력을 입증했습니다.이번 글에서는 이러한 결과를 만들어내기까지 저희가 마주했던 도전 과제들과, 이를 극복하기 위해 고민하고 노력했던 과정을 자세히 소개하고자 합니다.그림 2. Kanana-o와 글로벌 경쟁모델들의 음성 및 통합 모달리티 벤치마크 성능 비교특히, 아직 소개해드리지 못헀던 Kanana-a에 대해 먼저 자세하게 소개하고, 이를 Kanana-v와 결합하여 Kanana-o를 만든 과정을 설명드리겠습니다. 이어서 성능에 대한 자세한 정량 수치와 다양한 활용 예시들을 보여드리며 글을 마무리하도록 하겠습니다.사람과 기계가 소통하는 가장 자연스러운 방식은 ‘말하기’라고 할 수 있습니다. 음성은 텍스트보다 입력 속도가 빠르고, 시각적 주의를 요구하지 않으며, 몰입감 있는 소통 수단으로서도 강력합니다. 특히 운전 중, 운동 중, AR/VR 기기처럼 손이나 눈이 자유롭지 않은 환경에서는 텍스트보다 훨씬 직관적인 인터페이스가 됩니다.그뿐만 아니라, 음성은 단순한 정보 전달을 넘어 감정과 뉘앙스까지 담을 수 있는 소통의 수단입니다. 우리는 누군가의 말투, 속도, 억양, 리듬, 배경 소리까지 종합해 의미를 해석하고, 그에 맞는 방식으로 반응합니다.반면, 텍스트 중심 LLM은 이 모든 비 언어적 정보(paralinguistic cues)를 인식하지 못하고 단어 그 자체에만 반응합니다. 예를 들어, 떨리는 목소리로 말하는 “괜찮아요”는 문자로는 표현되지 않는 감정을 담고 있으며, 격앙된 고객의 말투에 맞춰 상담사가 말하는 속도를 낮추는 것도 텍스트만으로는 구현하기 어렵습니다.이처럼 실제 상황에서 사람과 사람 사이의 상호작용은 텍스트로 환원되기 어려운 정보들로 가득 차 있습니다.그래서, Audio LLM은 단순한 텍스트 LLM의 확장이 아니라, 인간과 기계 간 소통 방식을 근본적으로 바꾸는 새로운 패러다임이라고 할 수 있습니다. 이 섹션에서는 저희가 Audio LLM을 설계하며 겪은 기술적 고민과 구조적 선택에 대한 내용을 공유드리고자 합니다.Kanana-a의 개발 과정과 전체 구조Kanana-a는 텍스트와 음성을 함께 이해하고 생성할 수 있는 멀티모달 언어모델로, 전체 구조는 세 가지 주요 모듈로 구성됩니다.첫 번째는 오디오 인코딩(audio encoding) 모듈로, 입력된 음성 신호를 멜 스펙트로그램(Mel Spectrogram)으로 변환한 후, 오디오 인코더를 통해 LLM이 처리 가능한 형태의 임베딩 벡터로 압축합니다.두 번째는 LLM 기반 응답 생성 단계입니다. 이 과정에서 모델은 텍스트와 음성 임베딩을 함께 입력받아, 질의에 대한 의미를 통합적으로 이해하고 적절한 응답 시퀀스를 생성합니다.마지막으로, LLM에서 생성된 응답은 오디오 디코딩(audio decoding) 모듈을 통해 사람이 들을 수 있는 실제 음성 파형으로 복원됩니다. 이 단계에서는 LLM의 응답을 참고하여 이산적인 음성 토큰을 만들어낸 뒤 멜 디코더와 보코더가 함께 사용되어 자연스러운 음성 출력을 완성합니다.그림 3. 음성 이해 언어모델인 Kanana-a의 모델 구조. Voice Token LM으로부터 나오는 이산 음성 토큰을 실제 음성 파형으로 변경해주는 token-to-wav 합성 모듈은 그림에서 생략 되어있음.음성 데이터는 텍스트에 비해 입력 길이와 복잡도가 훨씬 높습니다. 예를 들어, “안녕하세요”와 같은 1초 분량의 인사말을 16kHz로 샘플링하면, 16,000개의 연속적인 숫자로 표현됩니다. 이처럼 단 몇 초의 음성도 수만 개의 숫자로 구성되기 때문에, 이를 그대로 대형 언어모델(LLM)에 입력하면 막대한 연산량과 지연(latency) 문제가 발생하게 됩니다.그렇다면 입력으로 주어지는 원본(raw) 음성 신호를 어떻게 하면 더 짧고 효율적인 형태로 바꿔 입력할 수 있을까요? 이 문제에 대한 저희의 고민과 경험을 바로 이어서 공유드리겠습니다.그림 4. 오디오 인코딩 모듈. 입력으로 들어오는 음성 신호가 mel spectrogram으로의 변환을 거쳐 Audio Encoder와 Audio Projector를 순차적으로 통과하며 LLM의 입력 벡터로 변환 됩니다.오디오 인코더: Raw 음성 신호를 LLM 친화적인 표현으로먼저, 입력된 음성 신호는 오디오 인코더(Audio Encoder)를 통해 일정 수준 압축된 피처 벡터(feature vector)로 변환됩니다. 일반적으로 멀티모달 언어모델에서는 각 모달리티에 대해 사전학습된 인코더(pretrained encoder)를 사용합니다.저희는 음성 인식 분야에서 널리 쓰이고 있는 OpenAI의 Whisper[1] 모델을 채택했습니다. Whisper는 96개 언어, 약 68만 시간 규모의 대규모 데이터를 학습한 모델로, MIT 라이선스 하에 공개되어 있어 제품을 개발하는 기업 입장에서도 접근성이 매우 좋은 모델이라고 할 수 있습니다.Whisper 인코더의 특징 중 하나는 높은 압축률인데요, 예를 들어, 초당 16,000개의 샘플로 구성된 음성 데이터를 멜 스펙트로그램으로 변환한 뒤 Whisper 인코더에 통과시키면, 초당 50개의 특징 벡터들만으로 표현할 수 있습니다.더욱 짧게 압축할 순 없을까? - 추가적인 Audio Projector의 설계Whisper 인코딩만으로도 압축률은 상당하지만, 1분
2025.05.01

좋아요

별로에요

더 잘 팔고, 더 잘 살 수 있는 방법
글. 남정연(Cleo) / UX Designer부제. 가격혜택 개선기여행 전 숙소를 고를 때, 합리적인 소비를 위해 가격과 혜택을 꼼꼼히 비교해보신 경험 다들 있지 않으신가요? 실제로 여기어때 UX 리서치팀의 고객 설문에서도 모텔, 호텔, 펜션 등 카테고리와 관계없이 가격이 최우선 탐색 조건이라는 결과가 나왔어요.이처럼 고객에게 가격 경쟁력을 잘 소구하여 구매 결정에 도움을 주려면, 탐색 과정 전반에 걸친 효과적인 가격 커뮤니케이션이 핵심이에요. 특가나 쿠폰을 제공하는 제휴점 입장에서도 혜택이 잘 드러나는 것이 매출과 직결되는 만큼, 그 중요성은 더욱 크다고 볼 수 있죠.오늘은 이토록 중요한 가격 혜택 커뮤니케이션을 어떻게 개선하고 실험했는지, 그 과정에서 고객과 제휴점 모두의 니즈(Needs)를 어떻게 반영했는지, 또 실험 결과를 분석해 어떤 추가 개선을 도출했는지에 대한 이야기를 담아보려해요.문제 인식: 우리는 가격 혜택 커뮤니케이션을 잘하고 있을까?당시 여기어때는 고객에게 더 경쟁력 있는 가격으로 상품을 제공하고, 구매 전환을 높이는 방법을 고민하고 있었습니다. 이를 위해 제휴점이 특가를 더 활발히 설정하도록 유도하는 ‘특가 활성화 프로젝트’도 준비 중이었죠.하지만 제휴점이 특가를 제공하더라도, 고객이 이를 명확히 인지하지 못하면 구매로 이어지기 어렵고, 곧 제휴점의 특가 제공 동기마저 떨어뜨릴 수 있어요. 제휴점 대상 설문에서도, ‘특가를 제공했음에도 고객에게 충분히 노출되지 않아 효과가 아쉽다’는 의견이 많았어요. 이는 자연스럽게 ‘지금 고객에게 제공되는 가격 혜택이 과연 잘 전달되고 있는가?’ 하는 질문으로 이어졌죠.이 질문에 대한 답을 얻기 위해 실제 고객을 대상으로 UT(Usability Test)를 진행했어요. 숙소 탐색부터 구매 직전까지의 과정을 관찰하며, 현재 제공되는 혜택을 고객이 얼마나 잘 인지하고 체감하는지 검증했죠.그 결과, 다음과 같은 주요 인사이트를 얻을 수 있었어요.AS IS UT 결과혜택 정보는 ‘최종 가격’을 중심으로 인지된다고객은 빠르게 탐색하며 최종 가격과 직결된 정보에만 주목했어요. 특히, 가격과 시각적으로 분리되어있는 특가 정보는 거의 인지하지 못했어요.특가 유형보다 ‘할인 여부’와 ‘혜택 크기’에 집중한다‘반짝특가’, ‘타임특가’ 등 특가 유형을 세분화해서 보여주고 있었지만, 고객에게는 큰 의미를 주지 못했어요. 고객은 단순히 ‘특가가 적용되었는지’와 ‘얼마나 할인되는지’에만 관심을 가졌어요.현재 제공되는 쿠폰 정보는 소구력이 약하다쿠폰 혜택이 잘 드러나지 않아, 고객은 실제보다 혜택이 없거나 적다고 느끼기 쉬운 구조였습니다.이렇게 정의된 문제를 바탕으로, 가격 혜택을 어떻게 더 직관적이고 강하게 커뮤니케이션할 수 있을지 고민하게 되었어요.가설 수립과 솔루션 제안: 최종가에 혜택과 할인율을 강조하면 어떨까?“적용된 혜택과 할인율을 시각적으로 강조하고 최종가 근처에서 명확히 보여준다면, 고객은 가격 혜택을 더 쉽게 인지하고 이해할 수 있을 것이다.”라는 가설을 기반으로, 두 가지 주요 솔루션을
4/29/2025

더 잘 팔고, 더 잘 살 수 있는 방법
글. 남정연(Cleo) / UX Designer부제. 가격혜택 개선기여행 전 숙소를 고를 때, 합리적인 소비를 위해 가격과 혜택을 꼼꼼히 비교해보신 경험 다들 있지 않으신가요? 실제로 여기어때 UX 리서치팀의 고객 설문에서도 모텔, 호텔, 펜션 등 카테고리와 관계없이 가격이 최우선 탐색 조건이라는 결과가 나왔어요.이처럼 고객에게 가격 경쟁력을 잘 소구하여 구매 결정에 도움을 주려면, 탐색 과정 전반에 걸친 효과적인 가격 커뮤니케이션이 핵심이에요. 특가나 쿠폰을 제공하는 제휴점 입장에서도 혜택이 잘 드러나는 것이 매출과 직결되는 만큼, 그 중요성은 더욱 크다고 볼 수 있죠.오늘은 이토록 중요한 가격 혜택 커뮤니케이션을 어떻게 개선하고 실험했는지, 그 과정에서 고객과 제휴점 모두의 니즈(Needs)를 어떻게 반영했는지, 또 실험 결과를 분석해 어떤 추가 개선을 도출했는지에 대한 이야기를 담아보려해요.문제 인식: 우리는 가격 혜택 커뮤니케이션을 잘하고 있을까?당시 여기어때는 고객에게 더 경쟁력 있는 가격으로 상품을 제공하고, 구매 전환을 높이는 방법을 고민하고 있었습니다. 이를 위해 제휴점이 특가를 더 활발히 설정하도록 유도하는 ‘특가 활성화 프로젝트’도 준비 중이었죠.하지만 제휴점이 특가를 제공하더라도, 고객이 이를 명확히 인지하지 못하면 구매로 이어지기 어렵고, 곧 제휴점의 특가 제공 동기마저 떨어뜨릴 수 있어요. 제휴점 대상 설문에서도, ‘특가를 제공했음에도 고객에게 충분히 노출되지 않아 효과가 아쉽다’는 의견이 많았어요. 이는 자연스럽게 ‘지금 고객에게 제공되는 가격 혜택이 과연 잘 전달되고 있는가?’ 하는 질문으로 이어졌죠.이 질문에 대한 답을 얻기 위해 실제 고객을 대상으로 UT(Usability Test)를 진행했어요. 숙소 탐색부터 구매 직전까지의 과정을 관찰하며, 현재 제공되는 혜택을 고객이 얼마나 잘 인지하고 체감하는지 검증했죠.그 결과, 다음과 같은 주요 인사이트를 얻을 수 있었어요.AS IS UT 결과혜택 정보는 ‘최종 가격’을 중심으로 인지된다고객은 빠르게 탐색하며 최종 가격과 직결된 정보에만 주목했어요. 특히, 가격과 시각적으로 분리되어있는 특가 정보는 거의 인지하지 못했어요.특가 유형보다 ‘할인 여부’와 ‘혜택 크기’에 집중한다‘반짝특가’, ‘타임특가’ 등 특가 유형을 세분화해서 보여주고 있었지만, 고객에게는 큰 의미를 주지 못했어요. 고객은 단순히 ‘특가가 적용되었는지’와 ‘얼마나 할인되는지’에만 관심을 가졌어요.현재 제공되는 쿠폰 정보는 소구력이 약하다쿠폰 혜택이 잘 드러나지 않아, 고객은 실제보다 혜택이 없거나 적다고 느끼기 쉬운 구조였습니다.이렇게 정의된 문제를 바탕으로, 가격 혜택을 어떻게 더 직관적이고 강하게 커뮤니케이션할 수 있을지 고민하게 되었어요.가설 수립과 솔루션 제안: 최종가에 혜택과 할인율을 강조하면 어떨까?“적용된 혜택과 할인율을 시각적으로 강조하고 최종가 근처에서 명확히 보여준다면, 고객은 가격 혜택을 더 쉽게 인지하고 이해할 수 있을 것이다.”라는 가설을 기반으로, 두 가지 주요 솔루션을
2025.04.29

좋아요

별로에요

CHANGELOG 자동화 커스텀으로 Git을 통한 형상관리에 날개달기
들어가며안녕하세요, 인포테인먼트CCS개발팀에서 프론트엔드 개발을 하고 있는 이민재 연구원입니다.개발을 하면서 개발자들이 가장 보편적으로 쓰는 형상관리 툴인 Git은 개발자가 어떤 Feature를 개발했는지, 어떤 수정사항을 진행했는지 편리하게 알 수 있습니다. Git의 commit message를 통해서 우리는 어떤 것이 바뀌었는지 알 수 있고, 이를 통해서 이력 관리를 할 수 있습니다.하지만, commit 메세지를 한 눈에 파악하는 것은 약간의 노력이 수반될 수 있습니다. Github에 있는 대표적인 오픈소스인 react 프로젝트를 예시로 들어보겠습니다.한 눈에 어떤 변경점이 개선이 되었는지, 그리고 버전별로 변경사항을 한 눈에 파악하기는 힘들지 않나요? 그렇다고 이 commit message를 한 눈에 보기 위해서 프로젝트를 pull 받고, git hash를 찾아서 어떤 변경점이 있었는지 찾는 것은 생산성 저하의 우려가 있을 수 있습니다. 그래서 대부분의 Open Source 라이브러리들을 이력을 CHANGELOG.md를 통해서 관리합니다.체인지로그(changelog, 변경 기록)는 웹 사이트나 프로그램을 제작하는 것 같은 어떤 프로젝트를 진행할 때에 변경 사항에 대한 기록입니다. 많은 오픈소스 프로젝트에서는 체인지로그 파일을 가장 상위에 포함해서 배포합니다. (출처: https://ko.wikipedia.org/wiki/%EC%B2%B4%EC%9D%B8%EC%A7%80%EB%A1%9C%EA%B7%B8)Frontend에서 Design System 제작에 많이 사용되는 Storybook의 CHANGELOG를 같이 한 번 보겠습니다.대규모 Open Source이다 보니, 모든 변경사항에 대해 자세하게 적어주지는 않았지만, Release Note와 같이 몇 버전에서는 어떠한 사항이 변경 및 수정이 되었는지 확인이 가능합니다.개발에 집중하여 코드를 작성하고, 버그 개선 및 코드 수정을 하는 것도 개발자에게 필수적인 역량이라고 생각이 되지만, 내가 쓴 코드를 같이 협업을 하는 동료들이 본다고 했을 때, 동료들에게 내가 어떤 부분을 수정했고 반영을 했는지 알려주는 "문서화" 작업도 협업에 있어서 필요한 역량이라고 생각합니다. 단순히 구두로 "연구원님~ *** 관련한 feature 추가 했으니 확인해보세요~" 라고 하는 것은 정확한 정보 전달을 해친다고 생각이 됩니다.Node 환경에서는 commit 메세지 기반의 변경 사항을 자동화 해주는 라이브러리가 있습니다. 물론 Java(Spring)에도 자동으로 commit 메세지 기반의 CHANGELOG를 만들어 주는 tool이 있지만, 본 포스팅에서는 Node 환경에서 사용할 수 있는 방법에 대해서 소개해드리겠습니다.conventional-commit rule"standard-version", "conventional-changelog", "release-please" 등의 여러가지 라이브러리들을 사용할 수 있는데요, "conventional-changelog"에 대해 소개합니다. "standard-version", "release-please" 들이 내부적으로 "conventional-changelog"를 dependency로 사용하고 있기 때문에 모든 원형에 대해서 소개하는 것이 더 적절하다고 생각했습니다들어가기에 앞서, conventional-commit rule에 대해서 소개합니다. https://www.conventionalcommits.org/en/v1.0.0/이름에서도 볼 수 있듯이, 공통적인 commit rule에 대해서 정의를 하는 프로젝트 입니다. 짧게 요약을 해보면 아래의 형식에 맞추어 commit 메세지를 작성을 하라는 의미입니다.하지만, 인포테인먼트CCS개발팀에는 내부적인 commit rule이 존재했습니다. conventional-commit rule과 크게 다르지 않지만, commit 메세지의 맨 앞에 들어가는 type에 대괄호를 붙이는 것 입니다. 아래와 같이 말이죠.conventional-changelog이러한 배경을 가지고 conventional-changelog에 대한 사용법을 공유하겠습니다. 이 라이브러리의 사용법 자체는 크게 어렵지 않습니다.이렇게 하면 CHANGELOG.md 파일이 생기면서, git log를 끌고와 CHANGELOG.md 파일을 생성해줍니다.하지만, 제가 직면한 문제는 바로 커스텀한 commit 메세지 rule이 있었다는 것입니다. conventional-changelog를 내부적으로 뜯어보면 commit message를 parsing하는 parser가 존재합니다. 그 파서는 아래와 같이 commit message를 파싱하고, 앞서서 간략하게 언급한 conventional-commit rule을 따르고 있었습니다.headerPattern을 보시면 당팀에서 사용하는 commit 메세지의 header의 대괄호에 대해서는 conventional-changelog의 parser가 제대로 파싱하지 못하고 있었습니다. 그래서, 위의 conventional-changelog 명령어를 수행하면 CHANGELOG.md에 빈 파일이 생성이 되었습니다.custom parser이 문제를 어떻게 하면 해결할 수 있을지 고민하다가, 명령어를 조금 더 주의깊게 살펴보았는데요 cli에서 -p, -i, -s 등 어떠한 옵션을 가지고 명령어가 동작하지 않을까 생각이 들었습니다. 라이브러리를 조금 더 공부하고, 깊게 들어가본 결과 cli 명령어를 수행할 때 넣을 수 있는 옵션들이 있다는 것을 알았습니다.(출처: https://github.com/conventional-changelog/conventional-changelog/blob/master/packages/conventional-changelog/src/cli/index.ts)여기에서 특히 집중했던 부분은 -p(--preset) 옵션이었습니다.기본적으로 제공해주는 cli 명령어는 angular 옵션으로 실행이 되고 있지 않을까 생각이 되어 이 부분을 custom한 parser로 대체하면 되지 않을까 생각했었습니다. 그래서 프로젝트 root directory
storybook
4/29/2025

CHANGELOG 자동화 커스텀으로 Git을 통한 형상관리에 날개달기
들어가며안녕하세요, 인포테인먼트CCS개발팀에서 프론트엔드 개발을 하고 있는 이민재 연구원입니다.개발을 하면서 개발자들이 가장 보편적으로 쓰는 형상관리 툴인 Git은 개발자가 어떤 Feature를 개발했는지, 어떤 수정사항을 진행했는지 편리하게 알 수 있습니다. Git의 commit message를 통해서 우리는 어떤 것이 바뀌었는지 알 수 있고, 이를 통해서 이력 관리를 할 수 있습니다.하지만, commit 메세지를 한 눈에 파악하는 것은 약간의 노력이 수반될 수 있습니다. Github에 있는 대표적인 오픈소스인 react 프로젝트를 예시로 들어보겠습니다.한 눈에 어떤 변경점이 개선이 되었는지, 그리고 버전별로 변경사항을 한 눈에 파악하기는 힘들지 않나요? 그렇다고 이 commit message를 한 눈에 보기 위해서 프로젝트를 pull 받고, git hash를 찾아서 어떤 변경점이 있었는지 찾는 것은 생산성 저하의 우려가 있을 수 있습니다. 그래서 대부분의 Open Source 라이브러리들을 이력을 CHANGELOG.md를 통해서 관리합니다.체인지로그(changelog, 변경 기록)는 웹 사이트나 프로그램을 제작하는 것 같은 어떤 프로젝트를 진행할 때에 변경 사항에 대한 기록입니다. 많은 오픈소스 프로젝트에서는 체인지로그 파일을 가장 상위에 포함해서 배포합니다. (출처: https://ko.wikipedia.org/wiki/%EC%B2%B4%EC%9D%B8%EC%A7%80%EB%A1%9C%EA%B7%B8)Frontend에서 Design System 제작에 많이 사용되는 Storybook의 CHANGELOG를 같이 한 번 보겠습니다.대규모 Open Source이다 보니, 모든 변경사항에 대해 자세하게 적어주지는 않았지만, Release Note와 같이 몇 버전에서는 어떠한 사항이 변경 및 수정이 되었는지 확인이 가능합니다.개발에 집중하여 코드를 작성하고, 버그 개선 및 코드 수정을 하는 것도 개발자에게 필수적인 역량이라고 생각이 되지만, 내가 쓴 코드를 같이 협업을 하는 동료들이 본다고 했을 때, 동료들에게 내가 어떤 부분을 수정했고 반영을 했는지 알려주는 "문서화" 작업도 협업에 있어서 필요한 역량이라고 생각합니다. 단순히 구두로 "연구원님~ *** 관련한 feature 추가 했으니 확인해보세요~" 라고 하는 것은 정확한 정보 전달을 해친다고 생각이 됩니다.Node 환경에서는 commit 메세지 기반의 변경 사항을 자동화 해주는 라이브러리가 있습니다. 물론 Java(Spring)에도 자동으로 commit 메세지 기반의 CHANGELOG를 만들어 주는 tool이 있지만, 본 포스팅에서는 Node 환경에서 사용할 수 있는 방법에 대해서 소개해드리겠습니다.conventional-commit rule"standard-version", "conventional-changelog", "release-please" 등의 여러가지 라이브러리들을 사용할 수 있는데요, "conventional-changelog"에 대해 소개합니다. "standard-version", "release-please" 들이 내부적으로 "conventional-changelog"를 dependency로 사용하고 있기 때문에 모든 원형에 대해서 소개하는 것이 더 적절하다고 생각했습니다들어가기에 앞서, conventional-commit rule에 대해서 소개합니다. https://www.conventionalcommits.org/en/v1.0.0/이름에서도 볼 수 있듯이, 공통적인 commit rule에 대해서 정의를 하는 프로젝트 입니다. 짧게 요약을 해보면 아래의 형식에 맞추어 commit 메세지를 작성을 하라는 의미입니다.하지만, 인포테인먼트CCS개발팀에는 내부적인 commit rule이 존재했습니다. conventional-commit rule과 크게 다르지 않지만, commit 메세지의 맨 앞에 들어가는 type에 대괄호를 붙이는 것 입니다. 아래와 같이 말이죠.conventional-changelog이러한 배경을 가지고 conventional-changelog에 대한 사용법을 공유하겠습니다. 이 라이브러리의 사용법 자체는 크게 어렵지 않습니다.이렇게 하면 CHANGELOG.md 파일이 생기면서, git log를 끌고와 CHANGELOG.md 파일을 생성해줍니다.하지만, 제가 직면한 문제는 바로 커스텀한 commit 메세지 rule이 있었다는 것입니다. conventional-changelog를 내부적으로 뜯어보면 commit message를 parsing하는 parser가 존재합니다. 그 파서는 아래와 같이 commit message를 파싱하고, 앞서서 간략하게 언급한 conventional-commit rule을 따르고 있었습니다.headerPattern을 보시면 당팀에서 사용하는 commit 메세지의 header의 대괄호에 대해서는 conventional-changelog의 parser가 제대로 파싱하지 못하고 있었습니다. 그래서, 위의 conventional-changelog 명령어를 수행하면 CHANGELOG.md에 빈 파일이 생성이 되었습니다.custom parser이 문제를 어떻게 하면 해결할 수 있을지 고민하다가, 명령어를 조금 더 주의깊게 살펴보았는데요 cli에서 -p, -i, -s 등 어떠한 옵션을 가지고 명령어가 동작하지 않을까 생각이 들었습니다. 라이브러리를 조금 더 공부하고, 깊게 들어가본 결과 cli 명령어를 수행할 때 넣을 수 있는 옵션들이 있다는 것을 알았습니다.(출처: https://github.com/conventional-changelog/conventional-changelog/blob/master/packages/conventional-changelog/src/cli/index.ts)여기에서 특히 집중했던 부분은 -p(--preset) 옵션이었습니다.기본적으로 제공해주는 cli 명령어는 angular 옵션으로 실행이 되고 있지 않을까 생각이 되어 이 부분을 custom한 parser로 대체하면 되지 않을까 생각했었습니다. 그래서 프로젝트 root directory
2025.04.29
storybook

좋아요

별로에요

산뜻하게 봄맞이 청소 어때요?
여기어때 컬처 라운지 ep. 6어느덧 옷차림이 가벼워지고 따스한 봄기운이 느껴지는 4월 말입니다. 봄은 겨우내 쌓인 먼지를 털어내고 새로운 마음으로 재정비하기도 참 좋은 계절이죠? 봄을 맞이해 여기어때는 몸과 마음, 일하는 공간까지 산뜻하게 리프레시할 수 있는 시간을 가졌어요.✨ 공간을 청소하며 몸과 마음도 리프레시이번 봄맞이 대청소 행사 또한 Culture TF에서 기획하고 진행했어요. TF는 항상 ‘어떻게 하면 구성원들이 여기어때에서 더 즐겁고 행복하게 일할 수 있을까?’ 고민하는데요. 우리가 매일 많은 시간을 보내는 업무 공간을 깨끗하고 쾌적하게 만들면 몸과 마음도 함께 리프레시할 수 있을 것이라고 생각했어요. 쾌적한 업무 환경은 업무 효율뿐 아니라 마음의 안정에도 긍정적인 영향을 주니까요 :)‘청소’라고 하면 조금은 귀찮고 힘든 일처럼 느껴질 수도 있겠죠? Culture TF는 어떻게 하면 이 시간을 조금 더 즐겁고 의미 있게 만들 수 있을지 여러 아이디어를 모았습니다. 몇 가지를 소개해 드릴게요.🎁 첫 번째, 정성 가득 개인 청소 키트처음엔 층별로 공용 청소 물품을 구비해두려고 했어요. 그런데 혹시나 자율좌석을 이용하시는 구성원분들은 어색해서 선뜻 청소를 시작하지 못할까 걱정이 되더라고요. 그래서 결국, 누구나 편하게 참여하실 수 있도록 개인별 청소 키트로 준비하게 되었답니다. 오전부터 박스들과 씨름한 끝에 300개 키트를 준비했고, 점심시간에 라운지에서 Culture TF 멤버들이 직접 포장한 키트를 나눠 드렸어요. 혹시 부족할 경우를 대비해 각 층별 공용 청소 물품도 비치 완료!개인별 청소 키트키트는 소독 티슈, 정전기 청소포, 섬유 향수, 마스크, 그리고 행사 로고 스티커까지! 개인의 책상과 주변 공간을 산뜻하게 청소하는 데 꼭 필요한 물품들로 알차게 구성했어요. 작은 물건 하나하나에도 ‘구성원들이 기분 좋게 청소를 시작하셨으면 좋겠다’는 Culture TF의 마음이 담겨있어요.❣️✅ 두 번째, 막막하지 않도록! 친절한 체크리스트“어디서부터 청소를 시작해야 할까?”, “뭘 중점적으로 닦아야 하지?” 막막함을 느낄 구성원들을 위해 친절한 청소 체크리스트를 제작했어요. 개인 업무 공간 청소 시 확인하면 좋을 항목들과, 여러 사람이 함께 사용하는 회의실 청소 시 체크할 항목들을 구분했어요. 이 체크리스트는 청소의 가이드라인이 되어주면서 동시에, 앞으로 ‘이 공간을 이렇게 깨끗하게 유지하자’는 약속의 의미도 담았어요.청소 체크리스트🙌 세 번째, 회의실 청소 지원개인 업무 공간뿐만 아니라, 모두가 함께 쓰는 회의실도 깨끗해져야겠죠? 각 층별 회의실은 청소 지원자를 선착순으로 모집했어요. 체크리스트와 함께 어떤 회의실을 청소해야 하는지 안내해 드렸습니다. 자발적으로 나서서 청소해 주신 감사한 분들을 위해, 청소 후 체크리스트를 가져오시면 예쁜 청소 아이템을 리워드로 드렸어요. 작지만 소소한 선물이 회의실을 더 깨끗하게 만드는 힘이 되었겠죠?자발적인 회의실 청소 후기 & 소소한 청소 선물🎉 네 번째, 함께 나누고 즐겨요내 자리만 청소하
4/29/2025

산뜻하게 봄맞이 청소 어때요?
여기어때 컬처 라운지 ep. 6어느덧 옷차림이 가벼워지고 따스한 봄기운이 느껴지는 4월 말입니다. 봄은 겨우내 쌓인 먼지를 털어내고 새로운 마음으로 재정비하기도 참 좋은 계절이죠? 봄을 맞이해 여기어때는 몸과 마음, 일하는 공간까지 산뜻하게 리프레시할 수 있는 시간을 가졌어요.✨ 공간을 청소하며 몸과 마음도 리프레시이번 봄맞이 대청소 행사 또한 Culture TF에서 기획하고 진행했어요. TF는 항상 ‘어떻게 하면 구성원들이 여기어때에서 더 즐겁고 행복하게 일할 수 있을까?’ 고민하는데요. 우리가 매일 많은 시간을 보내는 업무 공간을 깨끗하고 쾌적하게 만들면 몸과 마음도 함께 리프레시할 수 있을 것이라고 생각했어요. 쾌적한 업무 환경은 업무 효율뿐 아니라 마음의 안정에도 긍정적인 영향을 주니까요 :)‘청소’라고 하면 조금은 귀찮고 힘든 일처럼 느껴질 수도 있겠죠? Culture TF는 어떻게 하면 이 시간을 조금 더 즐겁고 의미 있게 만들 수 있을지 여러 아이디어를 모았습니다. 몇 가지를 소개해 드릴게요.🎁 첫 번째, 정성 가득 개인 청소 키트처음엔 층별로 공용 청소 물품을 구비해두려고 했어요. 그런데 혹시나 자율좌석을 이용하시는 구성원분들은 어색해서 선뜻 청소를 시작하지 못할까 걱정이 되더라고요. 그래서 결국, 누구나 편하게 참여하실 수 있도록 개인별 청소 키트로 준비하게 되었답니다. 오전부터 박스들과 씨름한 끝에 300개 키트를 준비했고, 점심시간에 라운지에서 Culture TF 멤버들이 직접 포장한 키트를 나눠 드렸어요. 혹시 부족할 경우를 대비해 각 층별 공용 청소 물품도 비치 완료!개인별 청소 키트키트는 소독 티슈, 정전기 청소포, 섬유 향수, 마스크, 그리고 행사 로고 스티커까지! 개인의 책상과 주변 공간을 산뜻하게 청소하는 데 꼭 필요한 물품들로 알차게 구성했어요. 작은 물건 하나하나에도 ‘구성원들이 기분 좋게 청소를 시작하셨으면 좋겠다’는 Culture TF의 마음이 담겨있어요.❣️✅ 두 번째, 막막하지 않도록! 친절한 체크리스트“어디서부터 청소를 시작해야 할까?”, “뭘 중점적으로 닦아야 하지?” 막막함을 느낄 구성원들을 위해 친절한 청소 체크리스트를 제작했어요. 개인 업무 공간 청소 시 확인하면 좋을 항목들과, 여러 사람이 함께 사용하는 회의실 청소 시 체크할 항목들을 구분했어요. 이 체크리스트는 청소의 가이드라인이 되어주면서 동시에, 앞으로 ‘이 공간을 이렇게 깨끗하게 유지하자’는 약속의 의미도 담았어요.청소 체크리스트🙌 세 번째, 회의실 청소 지원개인 업무 공간뿐만 아니라, 모두가 함께 쓰는 회의실도 깨끗해져야겠죠? 각 층별 회의실은 청소 지원자를 선착순으로 모집했어요. 체크리스트와 함께 어떤 회의실을 청소해야 하는지 안내해 드렸습니다. 자발적으로 나서서 청소해 주신 감사한 분들을 위해, 청소 후 체크리스트를 가져오시면 예쁜 청소 아이템을 리워드로 드렸어요. 작지만 소소한 선물이 회의실을 더 깨끗하게 만드는 힘이 되었겠죠?자발적인 회의실 청소 후기 & 소소한 청소 선물🎉 네 번째, 함께 나누고 즐겨요내 자리만 청소하
2025.04.29

좋아요

별로에요