logo
emoji
검색하기
어제 가장 많이 검색된 기술
emoji
가장 많이 읽은 글
logo
User-Agent vs. Feature Detection: 무엇을 언제 어떻게 써야 할까?
개발 시 사용자의 브라우저나 기기 환경에 따라 적절한 기능을 제공해야 하는 경우가 빈번하게 있습니다.해상도에 따라 반응형 디자인을 변경하거나, 모바일 / 폴드 / 태블릿 / 데스크탑 등 UX를 변경하는 경우는 많이 구현을 하곤 합니다.하지만 사용자 디바이스 / 접속 환경에 따라 기능을 변경하거나, UX를 향상시키기 위해 다르게 구현해야 한다면 어떨까요?이를 위해 두 가지 대표적인 방법인 'User-Agent Sniffing'과 'Feature Detection'에 대해 조사한 내용을 공유해 보고자 합니다.User-Agent Sniffing은 브라우저가 제공하는 User-Agent 문자열을 분석하여 기기나 브라우저를 식별하는 방식입니다.예를 들어, 특정 안드로이드 기기나 iOS 브라우저에서만 발생하는 문제를 해결하기 위해 사용할 수 있습니다.위 문자열에서 는 갤럭시 S8+ 모델을 나타냅니다(미국버전). 이를 통해 기기 모델을 특정할 수 있습니다.파싱을 통해 사용하는 것이 좋아 보이는데, 라이브러리로 나오는 것이 있어 아래에서 예제를 공유하겠습니다.하지만, User-Agent Sniffing은 약간의 단점이 있습니다:• None 새로운 브라우저나 기기가 등장하면 유지보수가 어려워집니다.• None 브라우저 업데이트로 인해 형식이 변경될 수 있습니다.• None 개인정보 보호 강화로 User-Agent 정보가 점점 제한되고 있습니다.실제로 크롬은 User-Agent Client Hints API를 도입하여 기존 User-Agent 문자열을 단순화하고 있습니다:Feature Detection은 브라우저가 특정 기능을 지원하는지 직접 검사하는 방식입니다.특정 API를 사용하기 전에 해당 API가 브라우저에 존재하는지 확인하고 조건적으로 코드를 실행하는 방식으로 체크합니다.간단한 예시로는 브라우저가 'fetch' API를 지원하는지 검사하는 코드입니다:이 접근법은 브라우저나 기기의 종류와 상관없이 기능이 지원되면 코드가 동작하고, 그렇지 않으면 fallback을 제공할 수 있어 훨씬 안전합니다.터치를 감지하거나, 웹 워커를 사용 가능한지, 로컬 스토리지에서 등을 유지 가능한지 사용 가능한지도 확인해야 합니다.두 방식을 구현한 라이브러리와 서비스도 있습니다.Modernizr (modernizr.com)는 Feature Detection을 쉽게 구현할 수 있게 도와주는 라이브러리입니다.사용자가 직접 API 지원 여부를 확인할 필요 없어 간편합니다.또한 Modernizr는 빌드 시 필요한 기능만 선택하여 파일 크기를 최적화할 수 있어서 꽤 유용합니다.이와 같이 필요한 기능들만 선택해서 build한 후 사용이 가능합니다.Sniffr (github.com/amoilanen/sniffr)는 User-Agent Sniffing을 구현한 라이브러리입니다.실제 써 봤는데, 따로 파싱을 구현할 필요가 없어 유용할 듯합니다.• None Android: User-Agent 문자열로 기기 모델까지 특정 가능합니다. 제조사별로 패턴이 다릅니다.• None iOS: 기기 종류(iPhone, iPad)는 구분 가능하나 정확한 모델 특정은 제한적입니다. iOS 13부터는 iPadOS가 데스크톱 모드로 동작할 때 Mac으로 인식될 수 있습니다.• None Web (MacOS/Windows): OS 버전은 알 수 있으나, 정확한 모델 특정은 불가능합니다.그 navigator 객체를 활용해 사용자 접속 정보를 가져오는 외 다른 방법들도 소개해보겠습니다.이런 것들을 항상 확인하고 구현하진 않겠지만, '아주 가끔씩' 필요한 경우가 있으니 이러한 함수가 있다는 것도 알면 좋을 것 같습니다.이렇게 두 방식을 혼합하여 사용자의 환경을 더욱 날카롭게 특정할 수도 있을 것 같습니다.이전에 말한 것처럼, 구글은 User-Agent 문자열의 정보를 점진적으로 줄이고 있습니다. 이제는 User-Agent Client Hints API를 활용해야 합니다:결론적으로, User-Agent Sniffing을 반드시 필요할 때만 제한적으로 사용하고, 기본적으로는 Feature Detection을 사용하는 것이 좋을 것 같습니다.또한 미래를 대비해 User-Agent Client Hints API와 같은 미래의 표준을 적용하는 것도 좋은 대안이 될 것 같습니다.간단히 userAgentData의 활용 형식에 대해서만 살펴보겠습니다.architecture, bitness, brands, ... 등이 있고, 버전, 브랜드(W3C User-Agent Client Hints에서 브랜드에 대해 확인할 수 있습니다.) 등도 확인이 가능합니다.네이버 D2 블로그 - User-Agent Client Hints의 도입, UA 프리징을 대비하라모더나이저(Feature detection 라이브러리)
5/12/2025
logo
User-Agent vs. Feature Detection: 무엇을 언제 어떻게 써야 할까?
개발 시 사용자의 브라우저나 기기 환경에 따라 적절한 기능을 제공해야 하는 경우가 빈번하게 있습니다.해상도에 따라 반응형 디자인을 변경하거나, 모바일 / 폴드 / 태블릿 / 데스크탑 등 UX를 변경하는 경우는 많이 구현을 하곤 합니다.하지만 사용자 디바이스 / 접속 환경에 따라 기능을 변경하거나, UX를 향상시키기 위해 다르게 구현해야 한다면 어떨까요?이를 위해 두 가지 대표적인 방법인 'User-Agent Sniffing'과 'Feature Detection'에 대해 조사한 내용을 공유해 보고자 합니다.User-Agent Sniffing은 브라우저가 제공하는 User-Agent 문자열을 분석하여 기기나 브라우저를 식별하는 방식입니다.예를 들어, 특정 안드로이드 기기나 iOS 브라우저에서만 발생하는 문제를 해결하기 위해 사용할 수 있습니다.위 문자열에서 는 갤럭시 S8+ 모델을 나타냅니다(미국버전). 이를 통해 기기 모델을 특정할 수 있습니다.파싱을 통해 사용하는 것이 좋아 보이는데, 라이브러리로 나오는 것이 있어 아래에서 예제를 공유하겠습니다.하지만, User-Agent Sniffing은 약간의 단점이 있습니다:• None 새로운 브라우저나 기기가 등장하면 유지보수가 어려워집니다.• None 브라우저 업데이트로 인해 형식이 변경될 수 있습니다.• None 개인정보 보호 강화로 User-Agent 정보가 점점 제한되고 있습니다.실제로 크롬은 User-Agent Client Hints API를 도입하여 기존 User-Agent 문자열을 단순화하고 있습니다:Feature Detection은 브라우저가 특정 기능을 지원하는지 직접 검사하는 방식입니다.특정 API를 사용하기 전에 해당 API가 브라우저에 존재하는지 확인하고 조건적으로 코드를 실행하는 방식으로 체크합니다.간단한 예시로는 브라우저가 'fetch' API를 지원하는지 검사하는 코드입니다:이 접근법은 브라우저나 기기의 종류와 상관없이 기능이 지원되면 코드가 동작하고, 그렇지 않으면 fallback을 제공할 수 있어 훨씬 안전합니다.터치를 감지하거나, 웹 워커를 사용 가능한지, 로컬 스토리지에서 등을 유지 가능한지 사용 가능한지도 확인해야 합니다.두 방식을 구현한 라이브러리와 서비스도 있습니다.Modernizr (modernizr.com)는 Feature Detection을 쉽게 구현할 수 있게 도와주는 라이브러리입니다.사용자가 직접 API 지원 여부를 확인할 필요 없어 간편합니다.또한 Modernizr는 빌드 시 필요한 기능만 선택하여 파일 크기를 최적화할 수 있어서 꽤 유용합니다.이와 같이 필요한 기능들만 선택해서 build한 후 사용이 가능합니다.Sniffr (github.com/amoilanen/sniffr)는 User-Agent Sniffing을 구현한 라이브러리입니다.실제 써 봤는데, 따로 파싱을 구현할 필요가 없어 유용할 듯합니다.• None Android: User-Agent 문자열로 기기 모델까지 특정 가능합니다. 제조사별로 패턴이 다릅니다.• None iOS: 기기 종류(iPhone, iPad)는 구분 가능하나 정확한 모델 특정은 제한적입니다. iOS 13부터는 iPadOS가 데스크톱 모드로 동작할 때 Mac으로 인식될 수 있습니다.• None Web (MacOS/Windows): OS 버전은 알 수 있으나, 정확한 모델 특정은 불가능합니다.그 navigator 객체를 활용해 사용자 접속 정보를 가져오는 외 다른 방법들도 소개해보겠습니다.이런 것들을 항상 확인하고 구현하진 않겠지만, '아주 가끔씩' 필요한 경우가 있으니 이러한 함수가 있다는 것도 알면 좋을 것 같습니다.이렇게 두 방식을 혼합하여 사용자의 환경을 더욱 날카롭게 특정할 수도 있을 것 같습니다.이전에 말한 것처럼, 구글은 User-Agent 문자열의 정보를 점진적으로 줄이고 있습니다. 이제는 User-Agent Client Hints API를 활용해야 합니다:결론적으로, User-Agent Sniffing을 반드시 필요할 때만 제한적으로 사용하고, 기본적으로는 Feature Detection을 사용하는 것이 좋을 것 같습니다.또한 미래를 대비해 User-Agent Client Hints API와 같은 미래의 표준을 적용하는 것도 좋은 대안이 될 것 같습니다.간단히 userAgentData의 활용 형식에 대해서만 살펴보겠습니다.architecture, bitness, brands, ... 등이 있고, 버전, 브랜드(W3C User-Agent Client Hints에서 브랜드에 대해 확인할 수 있습니다.) 등도 확인이 가능합니다.네이버 D2 블로그 - User-Agent Client Hints의 도입, UA 프리징을 대비하라모더나이저(Feature detection 라이브러리)
2025.05.12
emoji
좋아요
emoji
별로에요
logo
쉽게이해하는 GPT. 1편(다음단어 예측기. Base모델)
이번에 포스팅에서는 GPT라는게 어떻게 구성이 되어있고현재 많이 쓰이는 ChatGPT의 동작을 LLAMA모델을 통해서 대략적으로 알아봅니다.전체적인 문맥을 만드는 일은 굉장히 어렵지만현재 단어를 보고, 다음에 올 단어를 예측해보는일은 어느정도 가능한 일 입니다.위 문장만 주어질 경우 다음 단어가 무엇이 나와야 할지 맞추기 어렵지만까지 주어지면, 앞에있는 단어들을 통해서 해당하는 문장의 다음 단어가 일것이라고 대략적으로 예상해 볼 수 있습니다.(물론 도 맞지만요!)이처럼 문장이 주어지고, 그 문장 다음에 어떤 단어가 나올지를 맞추는게 GPT의 알파이자 오메가 라고 할 수 있습니다.이때 문장을 주고, 해당하는 문장에 따른 다음 문자를 예측하면 되는것이기 때문에기존 머신러닝의 : 과같은 형태의 데이터가 없더라도인터넷에 존재하는 모든 텍스트가 이런 의 데이터로 활용이 가능해 집니다.GPT는 이제는 유명해진 General Pretrained Transformer의 약자 입니다.full name에서 추론해 볼 수 있지만, 블라블라 인것을 알 수 있습니다.는 google의 attention is all you need에서 처음 등장한것으로 알고있습니다.그리고, 이 Transformer를 설명할 때 항상 아래그림이 등장하죠근데, 저만 그런가요?사실 이렇게 주어지고, 이해하라고하면 저는 잘 모르겠더라구요.그래서 조금더 설명을 추가해 봤습니다.조금은 설명을 추가해 봤습니다.• None 아니 데이터가 도대체 어디서 어디로 흐르는 것이냐아아ㅏ위 두가지를 반영 해봤는데요• None (왼쪽 남색부분)Inputs를 통해서 들어간 문자열은 Vector로 변환됩니다.• None (보라색 부분)1️⃣에서 처리가 완료된 Vector를 사용해서 뭔지 모르겠지만 Encoding 동작을 하면, 그 결과로 Input한 Text의 특성을 보유한 가 생성됩니다.• None (오른쪽 남색부분) 를 사용해서 이제 새로운 무언가를 출력해 내야합니다. 이때 가장먼저 이 들어갑니다. 이 역시 단어의 일종이어서, Vector로 변환됩니다.• None (초록색 부분) 를 의 특성을 뽑아내는 중간에 끼어넣고, 출력해야하는 Text의 특성을 뽑아냅니다.• None (주황색 부분)4️⃣에서 얻어진 출력 Text의 특성을 활용해서, 다음에 올 문자를 추측합니다.• None 5️⃣에서 얻어진 단어(Ex. Hello)와 을 합쳐서 를 만들고, 이 문자를 다시 3️⃣에다가 넣어줍니다.• None 이 나올때까지 3~6을 반복해 줍니다.여기서 없이 오른쪽 부분이 바로 인 것을 알 수 있고,는 다음단어는 예측할 때 입력문장의 정보까지 참고해서 예측한다고 할 수 있습니다.Transformer의 경우 입력된 값이있고, 입력된 값에 따른 적당한 출력값이 필요합니다.그래서 와 같이 단순하게 학습시킬 수 없고입력된 문장에 대응되는 적당한 결과문장이 필요합니다.여기서 이제 아이디어를 내는게그러면 그냥 입력 문장의 특성추출부분 없이, 바로 예측해버리면 되는거 아냐?그래서, 최신 GPT계열의 모델들의 경우 이 대세를 이루고 있습니다.그래서 입력문장의 특성추출을 별도로 분리하지않고입력문장을 그대로 출력문장의 단어예측에 집어넣는 방식이 바로 Decoder Only Model입니다.가 들어갈 경우 이라는 문자가 출력되게 모델의 가중치를 학습시키면 되고문장은 온라인 상에 넘쳐나기 때문에, 학습에 어려움이 없습니다.huggingface에 올라온 LLaMa2 모델을 살펴보면Decoder Only Transformer의 모습을 보여주는것을 확인할 수가 있습니다.이러한 Decoder Only Transformer에 천문학적인 문서를 통해서 다음 문자를 예측하게 만든 상태를또는 이라고 부릅니다.하지만 지금까지 본 내용 만으로는어떻게 GPT가 유저와 이 가능한지 예상하기 어렵습니다.GPT가 어떻게 유저와 이 가능한다는 다음 포스팅에서 다룹니다.
5/12/2025
logo
쉽게이해하는 GPT. 1편(다음단어 예측기. Base모델)
이번에 포스팅에서는 GPT라는게 어떻게 구성이 되어있고현재 많이 쓰이는 ChatGPT의 동작을 LLAMA모델을 통해서 대략적으로 알아봅니다.전체적인 문맥을 만드는 일은 굉장히 어렵지만현재 단어를 보고, 다음에 올 단어를 예측해보는일은 어느정도 가능한 일 입니다.위 문장만 주어질 경우 다음 단어가 무엇이 나와야 할지 맞추기 어렵지만까지 주어지면, 앞에있는 단어들을 통해서 해당하는 문장의 다음 단어가 일것이라고 대략적으로 예상해 볼 수 있습니다.(물론 도 맞지만요!)이처럼 문장이 주어지고, 그 문장 다음에 어떤 단어가 나올지를 맞추는게 GPT의 알파이자 오메가 라고 할 수 있습니다.이때 문장을 주고, 해당하는 문장에 따른 다음 문자를 예측하면 되는것이기 때문에기존 머신러닝의 : 과같은 형태의 데이터가 없더라도인터넷에 존재하는 모든 텍스트가 이런 의 데이터로 활용이 가능해 집니다.GPT는 이제는 유명해진 General Pretrained Transformer의 약자 입니다.full name에서 추론해 볼 수 있지만, 블라블라 인것을 알 수 있습니다.는 google의 attention is all you need에서 처음 등장한것으로 알고있습니다.그리고, 이 Transformer를 설명할 때 항상 아래그림이 등장하죠근데, 저만 그런가요?사실 이렇게 주어지고, 이해하라고하면 저는 잘 모르겠더라구요.그래서 조금더 설명을 추가해 봤습니다.조금은 설명을 추가해 봤습니다.• None 아니 데이터가 도대체 어디서 어디로 흐르는 것이냐아아ㅏ위 두가지를 반영 해봤는데요• None (왼쪽 남색부분)Inputs를 통해서 들어간 문자열은 Vector로 변환됩니다.• None (보라색 부분)1️⃣에서 처리가 완료된 Vector를 사용해서 뭔지 모르겠지만 Encoding 동작을 하면, 그 결과로 Input한 Text의 특성을 보유한 가 생성됩니다.• None (오른쪽 남색부분) 를 사용해서 이제 새로운 무언가를 출력해 내야합니다. 이때 가장먼저 이 들어갑니다. 이 역시 단어의 일종이어서, Vector로 변환됩니다.• None (초록색 부분) 를 의 특성을 뽑아내는 중간에 끼어넣고, 출력해야하는 Text의 특성을 뽑아냅니다.• None (주황색 부분)4️⃣에서 얻어진 출력 Text의 특성을 활용해서, 다음에 올 문자를 추측합니다.• None 5️⃣에서 얻어진 단어(Ex. Hello)와 을 합쳐서 를 만들고, 이 문자를 다시 3️⃣에다가 넣어줍니다.• None 이 나올때까지 3~6을 반복해 줍니다.여기서 없이 오른쪽 부분이 바로 인 것을 알 수 있고,는 다음단어는 예측할 때 입력문장의 정보까지 참고해서 예측한다고 할 수 있습니다.Transformer의 경우 입력된 값이있고, 입력된 값에 따른 적당한 출력값이 필요합니다.그래서 와 같이 단순하게 학습시킬 수 없고입력된 문장에 대응되는 적당한 결과문장이 필요합니다.여기서 이제 아이디어를 내는게그러면 그냥 입력 문장의 특성추출부분 없이, 바로 예측해버리면 되는거 아냐?그래서, 최신 GPT계열의 모델들의 경우 이 대세를 이루고 있습니다.그래서 입력문장의 특성추출을 별도로 분리하지않고입력문장을 그대로 출력문장의 단어예측에 집어넣는 방식이 바로 Decoder Only Model입니다.가 들어갈 경우 이라는 문자가 출력되게 모델의 가중치를 학습시키면 되고문장은 온라인 상에 넘쳐나기 때문에, 학습에 어려움이 없습니다.huggingface에 올라온 LLaMa2 모델을 살펴보면Decoder Only Transformer의 모습을 보여주는것을 확인할 수가 있습니다.이러한 Decoder Only Transformer에 천문학적인 문서를 통해서 다음 문자를 예측하게 만든 상태를또는 이라고 부릅니다.하지만 지금까지 본 내용 만으로는어떻게 GPT가 유저와 이 가능한지 예상하기 어렵습니다.GPT가 어떻게 유저와 이 가능한다는 다음 포스팅에서 다룹니다.
2025.05.12
emoji
좋아요
emoji
별로에요
logo
AI로 생성한 이미지는 어떻게 평가할까요? (블랙박스 최적화 적용편)
생성형 AI 모델로 이미지 생성은 쉽죠, 그런데 '좋은 이미지' 생성도 쉬웠으면 좋겠어요!저희 회사에는 고유한 비율로 최소한의 디테일만 유지한 채 인체와 개체를 정의하는 이미지 스타일인 'LINE 스타일'이 존재합니다(참고). 저희 팀에서는 생성형 AI를 이용해 이 스타일이 적용된 이미지를 프롬프트만으로 생성하는 텍스트 투 이미지(text-to-image) 모델을 만드는 프로젝트를 진행했습니다.이 프로젝트는 사내 디자이너분들의 반복적인 이미지 생성 업무를 최소화하기 위해 시작했습니다. 사내 디자인 업무 중에는 상황에 맞게 이미지를 조금씩 다른 이미지를 그리는 업무가 있는데요. 이 작업을 자동화할 수 있다면 디자이너 분들이 보다 창의성을 요하는 업무에 집중할 수 있는 환경이 조성될 것이라고 믿었습니다.아래 이미지는 LINE 스타일에 따라 제작된 이미지로, 저희가 원하는 최종 결과물의 스타일과 수준을 보여줍니다.늘 그렇듯 생성형 AI 모델이 항상 좋은 이미지를 생성하도록 만드는 것은 쉽지 않았습니다. 예를 들어 아래 예시와 같이 'hold the LINE'이라는 피켓을 들고 있는 여성의 이미지를 생성하는 일을 생각해 보겠습니다. LINE 스타일과 유사한 이미지가 생성될 수도 있겠으나, 그렇지 않은 이미지들도 자주 생성될 것입니다. 실제로 아래 두 이미지 생성에 사용한 모델은 동일한 모델입니다. 단지 이미지 생성 시 설정한 하이퍼파라미터만 다를 뿐입니다(하이퍼파라미터에 대해서는 뒤에서 자세히 설명하겠습니다).* 이미지를 우클릭해서 새로운 탭이나 창에서 열면 이미지를 원본 크기로 확인하실 수 있습니다.좋은 이미지를 생성하기 위해 먼저 살펴볼 것이 글에서는 먼저 AI를 이용해 이미지를 생성하는 방법부터 살펴보겠습니다. 디퓨전(Diffusion) 모델로 시작해 스테이블 디퓨전(Stable Diffusion) 계열의 모델을 중점적으로 살펴보고자 하며, 스테이블 디퓨전 모델로 이미지 생성 시 널리 사용되는 여러 하이퍼파라미터와 각각의 기능도 함께 소개하겠습니다.좋은 이미지를 생성하는 방법을 알아내기 위해서는 이미지를 여러 번 생성해 봐야 하기 때문에 보통 몇 가지 하이퍼파라미터를 선정해 수치를 조정해 가며 이미지를 하나씩 생성해 보게 되는데요. 특정 범위 안에서 여러 값을 바꿔가며 이미지를 생성하는 일은 엄청난 수고가 필요한 일입니다. 따라서 자동화할 수 있다면 좋겠죠. 이런 작업을 자동화하려면 우선 '좋은 이미지'라는 게 무엇인지 수치화해 평가할 수 있어야 합니다. 이에 저희는 앞서 설명했던 이미지 평가 방법(참고: AI로 생성한 이미지는 어떻게 평가할까요? (기본편)) 중 일부를 소개하고, 이것을 활용한 하이퍼파라미터 탐색 방법을 소개하려고 합니다. 이미지를 수치화해서 평가하는 방법 외에도 프롬프트를 활용한 하이퍼파라미터 평가 방법도 소개할 예정이니 많은 관심 부탁드리며 본격적으로 시작해 보겠습니다.AI가 이미지를 생성하는 방법우선 생성 모델이 어떻게 이미지를 생성하는지 디퓨전 모델과 스테이블 디퓨전 모델을 중심으로 간략히 살펴보겠습니다(이후 설명은 스테이블 디퓨전 모델이 기준입니다).디퓨전 모델은 이미지 생성 분야에서 널리 사용하는 접근 방식 중 하나인 디퓨전 프로세스로 이미지를 학습 및 생성하는 모델입니다. 디퓨전 프로세스는 이미지의 노이즈를 점진적으로 제거(denoise)해 고품질의 이미지를 생성하는 방식입니다.• 전방향 디퓨전 프로세스: 디퓨전 프로세스는 원본 이미지에 점진적으로 노이즈를 추가해 이미지를 완전히 무작위한 상태로 변환하 는 과정입니다. 각 단계에서 일정량의 가우스 잡음(Gaussian noise)을 추가하는데요. 노이즈를 추가하는 방식은 마르코프 체인(Markov chain)으로 모델링되며, 각 단계는 이전 단계의 결과에 의존하지 않고 독립적으로 진행됩니다.• 역방향 노이즈 제거 프로세스: 노이즈 제거 프로세스는 노이즈가 추가된 이미지로부터 원본 이미지를 복원하는 과정입니다. 노이즈는 학습된 모델을 이용해 제거하는데요. 한 번에 제거하는 것이 아니라 점진적으로 제거해 초기 노이즈가 원본 이미지에 가까운 상태가 되도록 복원해 나갑니다. 이를 위해 모델은 현재 상태의 노이즈 이미지와 각 단계별로 노이즈를 제거할 확률 분포를 학습합니다. 즉, 제거할 노이즈 예측 값은 확률적(stochastic)으로 결정됩니다.이미지는 샘플링된 랜덤 가우스 잡음에 역방향 노이즈 제거 프로세스를 적용하는 형태로 생성됩니다.스테이블 디퓨전(이하 SD)은 디퓨전 모델의 한 구현체입니다. SD의 특징을 간략히 살펴보겠습니다.기존 디퓨전 모델은 앞서 살펴본 디퓨전 프로세스를 '픽셀 공간(pixel space)'에서 적용합니다. 따라서 큰 이미지(예: 1024x1024 픽셀)를 생성할 때에는 매우 많은 연산량이 필요합니다.이런 단점을 개선하기 위해 픽셀 공간이 아닌 '잠재 공간(latent space)'에서 디퓨전 프로세스를 적용하는 SD 모델이 제안됐습니다. 즉 기존 디퓨전 모델이 이미지 자체에서 노이즈를 줄이는 개념이라면, SD 모델은 이미지의 '잠재 벡터(latent vector)'에서 노이즈를 줄이는 개념입니다. 여기서 잠재 벡터는 잠재 공간에서의 위치이기 때문에 임베딩이라고 생각해도 무방합니다. 이 잠재 벡터는 이미지를 변분오토인코더(variational autoencoder, 이하 VAE)로 인코드해 생성하고, 이미지는 이 잠재 벡터를 VAE로 디코드해 생성합니다.이미지 생성 방식 중 텍스트를 추가 정보로 제공하는 텍스트 투 이미지 방식에서는 이미지를 생성할 때 노이즈 제거 과정에서 텍스트 임베딩 생성에 어텐션(attention) 메커니즘을 활용하며, 이미지 생성 모델을 파인튜닝할 때는 주로 노이즈 제거기(denoiser)인 U-Net을 파인튜닝합니다.저희 실험에서는 SD의 초기 버전인 SD1을 쓰지 않고 SDXL(SD-xlarge)과 SD3.5을 사용했습니다. 이 두 모델은 초기 버전의 SD 모델의 파라미터 수 증가에 따라 개량된 모델입니다(참고로 이 글에 첨부된 이미지는 대부분 SD3.5로 생성했습니다).SDXL의 구조는 SD와 큰 차이는 없습니다. 다만 텍스트 인코더(CLIP
5/12/2025
logo
AI로 생성한 이미지는 어떻게 평가할까요? (블랙박스 최적화 적용편)
생성형 AI 모델로 이미지 생성은 쉽죠, 그런데 '좋은 이미지' 생성도 쉬웠으면 좋겠어요!저희 회사에는 고유한 비율로 최소한의 디테일만 유지한 채 인체와 개체를 정의하는 이미지 스타일인 'LINE 스타일'이 존재합니다(참고). 저희 팀에서는 생성형 AI를 이용해 이 스타일이 적용된 이미지를 프롬프트만으로 생성하는 텍스트 투 이미지(text-to-image) 모델을 만드는 프로젝트를 진행했습니다.이 프로젝트는 사내 디자이너분들의 반복적인 이미지 생성 업무를 최소화하기 위해 시작했습니다. 사내 디자인 업무 중에는 상황에 맞게 이미지를 조금씩 다른 이미지를 그리는 업무가 있는데요. 이 작업을 자동화할 수 있다면 디자이너 분들이 보다 창의성을 요하는 업무에 집중할 수 있는 환경이 조성될 것이라고 믿었습니다.아래 이미지는 LINE 스타일에 따라 제작된 이미지로, 저희가 원하는 최종 결과물의 스타일과 수준을 보여줍니다.늘 그렇듯 생성형 AI 모델이 항상 좋은 이미지를 생성하도록 만드는 것은 쉽지 않았습니다. 예를 들어 아래 예시와 같이 'hold the LINE'이라는 피켓을 들고 있는 여성의 이미지를 생성하는 일을 생각해 보겠습니다. LINE 스타일과 유사한 이미지가 생성될 수도 있겠으나, 그렇지 않은 이미지들도 자주 생성될 것입니다. 실제로 아래 두 이미지 생성에 사용한 모델은 동일한 모델입니다. 단지 이미지 생성 시 설정한 하이퍼파라미터만 다를 뿐입니다(하이퍼파라미터에 대해서는 뒤에서 자세히 설명하겠습니다).* 이미지를 우클릭해서 새로운 탭이나 창에서 열면 이미지를 원본 크기로 확인하실 수 있습니다.좋은 이미지를 생성하기 위해 먼저 살펴볼 것이 글에서는 먼저 AI를 이용해 이미지를 생성하는 방법부터 살펴보겠습니다. 디퓨전(Diffusion) 모델로 시작해 스테이블 디퓨전(Stable Diffusion) 계열의 모델을 중점적으로 살펴보고자 하며, 스테이블 디퓨전 모델로 이미지 생성 시 널리 사용되는 여러 하이퍼파라미터와 각각의 기능도 함께 소개하겠습니다.좋은 이미지를 생성하는 방법을 알아내기 위해서는 이미지를 여러 번 생성해 봐야 하기 때문에 보통 몇 가지 하이퍼파라미터를 선정해 수치를 조정해 가며 이미지를 하나씩 생성해 보게 되는데요. 특정 범위 안에서 여러 값을 바꿔가며 이미지를 생성하는 일은 엄청난 수고가 필요한 일입니다. 따라서 자동화할 수 있다면 좋겠죠. 이런 작업을 자동화하려면 우선 '좋은 이미지'라는 게 무엇인지 수치화해 평가할 수 있어야 합니다. 이에 저희는 앞서 설명했던 이미지 평가 방법(참고: AI로 생성한 이미지는 어떻게 평가할까요? (기본편)) 중 일부를 소개하고, 이것을 활용한 하이퍼파라미터 탐색 방법을 소개하려고 합니다. 이미지를 수치화해서 평가하는 방법 외에도 프롬프트를 활용한 하이퍼파라미터 평가 방법도 소개할 예정이니 많은 관심 부탁드리며 본격적으로 시작해 보겠습니다.AI가 이미지를 생성하는 방법우선 생성 모델이 어떻게 이미지를 생성하는지 디퓨전 모델과 스테이블 디퓨전 모델을 중심으로 간략히 살펴보겠습니다(이후 설명은 스테이블 디퓨전 모델이 기준입니다).디퓨전 모델은 이미지 생성 분야에서 널리 사용하는 접근 방식 중 하나인 디퓨전 프로세스로 이미지를 학습 및 생성하는 모델입니다. 디퓨전 프로세스는 이미지의 노이즈를 점진적으로 제거(denoise)해 고품질의 이미지를 생성하는 방식입니다.• 전방향 디퓨전 프로세스: 디퓨전 프로세스는 원본 이미지에 점진적으로 노이즈를 추가해 이미지를 완전히 무작위한 상태로 변환하 는 과정입니다. 각 단계에서 일정량의 가우스 잡음(Gaussian noise)을 추가하는데요. 노이즈를 추가하는 방식은 마르코프 체인(Markov chain)으로 모델링되며, 각 단계는 이전 단계의 결과에 의존하지 않고 독립적으로 진행됩니다.• 역방향 노이즈 제거 프로세스: 노이즈 제거 프로세스는 노이즈가 추가된 이미지로부터 원본 이미지를 복원하는 과정입니다. 노이즈는 학습된 모델을 이용해 제거하는데요. 한 번에 제거하는 것이 아니라 점진적으로 제거해 초기 노이즈가 원본 이미지에 가까운 상태가 되도록 복원해 나갑니다. 이를 위해 모델은 현재 상태의 노이즈 이미지와 각 단계별로 노이즈를 제거할 확률 분포를 학습합니다. 즉, 제거할 노이즈 예측 값은 확률적(stochastic)으로 결정됩니다.이미지는 샘플링된 랜덤 가우스 잡음에 역방향 노이즈 제거 프로세스를 적용하는 형태로 생성됩니다.스테이블 디퓨전(이하 SD)은 디퓨전 모델의 한 구현체입니다. SD의 특징을 간략히 살펴보겠습니다.기존 디퓨전 모델은 앞서 살펴본 디퓨전 프로세스를 '픽셀 공간(pixel space)'에서 적용합니다. 따라서 큰 이미지(예: 1024x1024 픽셀)를 생성할 때에는 매우 많은 연산량이 필요합니다.이런 단점을 개선하기 위해 픽셀 공간이 아닌 '잠재 공간(latent space)'에서 디퓨전 프로세스를 적용하는 SD 모델이 제안됐습니다. 즉 기존 디퓨전 모델이 이미지 자체에서 노이즈를 줄이는 개념이라면, SD 모델은 이미지의 '잠재 벡터(latent vector)'에서 노이즈를 줄이는 개념입니다. 여기서 잠재 벡터는 잠재 공간에서의 위치이기 때문에 임베딩이라고 생각해도 무방합니다. 이 잠재 벡터는 이미지를 변분오토인코더(variational autoencoder, 이하 VAE)로 인코드해 생성하고, 이미지는 이 잠재 벡터를 VAE로 디코드해 생성합니다.이미지 생성 방식 중 텍스트를 추가 정보로 제공하는 텍스트 투 이미지 방식에서는 이미지를 생성할 때 노이즈 제거 과정에서 텍스트 임베딩 생성에 어텐션(attention) 메커니즘을 활용하며, 이미지 생성 모델을 파인튜닝할 때는 주로 노이즈 제거기(denoiser)인 U-Net을 파인튜닝합니다.저희 실험에서는 SD의 초기 버전인 SD1을 쓰지 않고 SDXL(SD-xlarge)과 SD3.5을 사용했습니다. 이 두 모델은 초기 버전의 SD 모델의 파라미터 수 증가에 따라 개량된 모델입니다(참고로 이 글에 첨부된 이미지는 대부분 SD3.5로 생성했습니다).SDXL의 구조는 SD와 큰 차이는 없습니다. 다만 텍스트 인코더(CLIP
2025.05.12
emoji
좋아요
emoji
별로에요
logo
반복 업무의 구원자, AI 슬랙봇 “도비”의 개발 여정
이번에는 슬랙과 지라의 반복 업무를 자동화한 AI 슬랙봇 ‘도비’의 개발 여정을 소개합니다. 별도 인프라나 복잡한 코딩 없이, GPT와 협업해 단순 명령으로 티켓을 생성하고 업무 시간을 크게 절약한 실전 사례입니다.쌓여가는 슬랙 쓰레드와 누락되는 지라 티켓업무를 위한 필수 도구인 슬랙과 지라! 하지만 이런 경험 다들 있으시죠? 회의 다녀온 사이 기하급수적으로 늘어난 쓰레드 댓글들, 급한 업무 처리하다 깜빡한 지라 티켓 생성까지. 이런 반복적인 업무는 생각보다 많은, 그리고 소중한 시간을 소모하게 만들어요.“회의를 갔다 오니까 갑자기 쓰레드 댓글이 엄청나게 쌓여있거나 아니면 중간에 멘션 된 경우 다들 있으시죠? 저는 이 긴 내용을 파악을 하다 보면 생각보다 시간을 꽤 사용하게 되더라고요.”‘도비' 는 플랫폼 PM 혜연님의 이런 일상적인 고민에서 시작됐어요. 특히 주문 관련 에러나 요청이 들어왔을 때 대응하느라 정신없이 일하다 보면 지라 티켓 생성을 자주 깜빡하게 되고, 이는 결국 중요한 이슈나 업무 트래킹 누락으로 이어지는 문제가 있었죠. 작년 체크아웃 운영 티켓만 280건, 티켓 생성에만 약 840분(14시간)이 소요된다는 계산이 나왔어요. 많은 직원들이 이런 반복 작업의 비효율성을 인지하고 있었지만, 주문 개발팀의 규원님 말씀처럼 현실은 달랐습니다.“운영 업무에 치여 아무것도 할 여유가 없었어요. 하지만 짧은 시간에도 AI 를 활용해 문제를 해결할 수 있을거라는 확신이 생겼고, 미뤄뒀던 일을 이제는 AI를 활용해 빠르게 해결해보려고 했어요.”현업에 치여 실천으로 옮기지 못하는 상황, 여러분들도 공감하실 거예요. 이런 상황에서규원님과 혜연님은 AI를 활용한 실질적인 해결책을 모색하기 시작했습니다.슬랙봇 ‘도비'GPT와 함께 시작한 슬랙봇 ‘도비’ 개발 여정규원님은 개발팀 매니저로서 반복적인 업무를 AI로 자동화할 방법을 오랫동안 고민해왔어요. 하지만 생각만으로는 아무것도 변하지 않았죠.규원님과 혜연님은 슬랙봇 개발이라는 공통의 목표를 세웠어요. 이 봇의 이름은 ‘도비’! 도비는 두 가지 핵심 기능을 제공합니다: 첫째, 슬랙 쓰레드를 한 방에 요약하는 ‘요약 도비’, 둘째, 내용을 요약해 지라 티켓까지 자동으로 생성하는 ‘지라 도비’예요. 개발 과정은 ChatGPT에게 물어보는 것으로 시작됐습니다. 규원님은 슬랙봇을 빠르게 만드는 방법부터 서버와의 연결, 쓰레드 내용 수집 방법까지 단계별로 GPT에게 질문했어요.도비의 주요 기능“슬랙에 특정 명령을 호출해서 해당 스레드에 있는 내용을 정리하는 것이 제 첫번째 요구사항이었어요.”이 과정에서 규원님은 몇 가지 원칙을 세웠는데요, 직접 많은 양의 코드를 생산하거나 DB, 인프라를 다루지 않고 에너지를 최소한으로 쓰겠다는 것이었습니다.“제가 코딩을 뭔가 주도적으로 하지 않는다가 첫 번째였고요. DB를 안 쓰는 게 두 번째였고 그리고 인프라도 안 쓰는 게 목적이었어요. 그러니까 여기에 내가 뭔가 다른 거를 하겠다는 에너지를 안 쓰려는 게 목적이었고…”이처럼 최소한의 개발 노력으로 최대한의 효과를 내
jira
slack
5/11/2025
logo
반복 업무의 구원자, AI 슬랙봇 “도비”의 개발 여정
이번에는 슬랙과 지라의 반복 업무를 자동화한 AI 슬랙봇 ‘도비’의 개발 여정을 소개합니다. 별도 인프라나 복잡한 코딩 없이, GPT와 협업해 단순 명령으로 티켓을 생성하고 업무 시간을 크게 절약한 실전 사례입니다.쌓여가는 슬랙 쓰레드와 누락되는 지라 티켓업무를 위한 필수 도구인 슬랙과 지라! 하지만 이런 경험 다들 있으시죠? 회의 다녀온 사이 기하급수적으로 늘어난 쓰레드 댓글들, 급한 업무 처리하다 깜빡한 지라 티켓 생성까지. 이런 반복적인 업무는 생각보다 많은, 그리고 소중한 시간을 소모하게 만들어요.“회의를 갔다 오니까 갑자기 쓰레드 댓글이 엄청나게 쌓여있거나 아니면 중간에 멘션 된 경우 다들 있으시죠? 저는 이 긴 내용을 파악을 하다 보면 생각보다 시간을 꽤 사용하게 되더라고요.”‘도비' 는 플랫폼 PM 혜연님의 이런 일상적인 고민에서 시작됐어요. 특히 주문 관련 에러나 요청이 들어왔을 때 대응하느라 정신없이 일하다 보면 지라 티켓 생성을 자주 깜빡하게 되고, 이는 결국 중요한 이슈나 업무 트래킹 누락으로 이어지는 문제가 있었죠. 작년 체크아웃 운영 티켓만 280건, 티켓 생성에만 약 840분(14시간)이 소요된다는 계산이 나왔어요. 많은 직원들이 이런 반복 작업의 비효율성을 인지하고 있었지만, 주문 개발팀의 규원님 말씀처럼 현실은 달랐습니다.“운영 업무에 치여 아무것도 할 여유가 없었어요. 하지만 짧은 시간에도 AI 를 활용해 문제를 해결할 수 있을거라는 확신이 생겼고, 미뤄뒀던 일을 이제는 AI를 활용해 빠르게 해결해보려고 했어요.”현업에 치여 실천으로 옮기지 못하는 상황, 여러분들도 공감하실 거예요. 이런 상황에서규원님과 혜연님은 AI를 활용한 실질적인 해결책을 모색하기 시작했습니다.슬랙봇 ‘도비'GPT와 함께 시작한 슬랙봇 ‘도비’ 개발 여정규원님은 개발팀 매니저로서 반복적인 업무를 AI로 자동화할 방법을 오랫동안 고민해왔어요. 하지만 생각만으로는 아무것도 변하지 않았죠.규원님과 혜연님은 슬랙봇 개발이라는 공통의 목표를 세웠어요. 이 봇의 이름은 ‘도비’! 도비는 두 가지 핵심 기능을 제공합니다: 첫째, 슬랙 쓰레드를 한 방에 요약하는 ‘요약 도비’, 둘째, 내용을 요약해 지라 티켓까지 자동으로 생성하는 ‘지라 도비’예요. 개발 과정은 ChatGPT에게 물어보는 것으로 시작됐습니다. 규원님은 슬랙봇을 빠르게 만드는 방법부터 서버와의 연결, 쓰레드 내용 수집 방법까지 단계별로 GPT에게 질문했어요.도비의 주요 기능“슬랙에 특정 명령을 호출해서 해당 스레드에 있는 내용을 정리하는 것이 제 첫번째 요구사항이었어요.”이 과정에서 규원님은 몇 가지 원칙을 세웠는데요, 직접 많은 양의 코드를 생산하거나 DB, 인프라를 다루지 않고 에너지를 최소한으로 쓰겠다는 것이었습니다.“제가 코딩을 뭔가 주도적으로 하지 않는다가 첫 번째였고요. DB를 안 쓰는 게 두 번째였고 그리고 인프라도 안 쓰는 게 목적이었어요. 그러니까 여기에 내가 뭔가 다른 거를 하겠다는 에너지를 안 쓰려는 게 목적이었고…”이처럼 최소한의 개발 노력으로 최대한의 효과를 내
2025.05.11
jira
slack
emoji
좋아요
emoji
별로에요
logo
Qwen3 의 Hybrid thinking mode
2025년 4월 29일 새벽에 Alibaba의 Qwen3 가 릴리즈되었다.Technical report 가 공개되지 않고, 블로그로만 공개되었기 때문에 학습이 어떻게 이루어졌는지는 아주 제한적으로 공개되었다.모델은 총 6개로 MoE 모델 2개와 Dense 모델 6개로 구성되었다.MoE 모델은 235B (22B activate), 30B (3B activate), Dense 모델은 32B, 14B, 8B, 4B, 1.7B, 0.6B 의 사이즈다.블로그 글에 따르면 각각 가장 큰 모델만 학습한 뒤, strong-to-weak distillation 을 통해 나머지 모델들을 학습한 것으로 보인다.아마도 base model 들은 pruning 기법들을 통해서 사이즈를 줄인 것 같다. (예상컨데 절반정도씩 줄여나간 것이 아닐까 싶다)사실 technical report 가 공개되지 않아서 학습 방법에 대해서는 아직 확실하게 파악하기 어렵다.그러나 공개된 것 중에 흥미로운 부분이 있었는데, 바로 Hybrid Thinking mode 이라는 것이다.Qwen3 공식 블로그에 따르면 Qwen3 는 thinking, 그러니까 reasoning 이 필요한 어려운 문제나 정확도를 요구하는 task 를 해결할 때에는 test-time reasoning 을 사용하고,빠르게 답변이 필요한 경우에는 think 를 끄고 그냥 답변을 제공하도록 학습되었다.이는 Claude-sonnet-3.7 에서 처음으로 제공했던 방식인데, 내가 알기로 명시적으로 open-source 에서 이를 가능하게 한 것은 처음이다.그렇다면 어떻게 on/off 를 구현했는가? Qwen3 는 두 가지 방법으로 on/off 를 제어하고 있다.유저나 시스템 턴에 , 명령어를 명시적으로 사용하면 thinking 을 제어할 수 있다. 예시를 살펴보자.이에 대한 답변은그리고 옵션 사용한 경우에는이에 대한 답변은, 토큰을 사용하여 reasoning 을 하고, 최종 답변하는 것을 볼 수 있다.아마도 이는 학습 시 thinking 없는 데이터는 를, 있는 데이터는 을 사용하여 학습한 것으로 보인다.즉, 스위치 토큰을 학습에 사용하여, reasoning On/Off 를 제어하는 방법이라고 볼 수 있다.또 다른 방법은 이라는 파라미터를 사용하는 것이다. Qwen3 블로그를 보면 아래와 같은 방법이 나와 있다.과연 옵션을 주면 무엇이 달라지는 것일까?을 보면 Qwen3 의 chat_template 이 있다. 여기서 해당 옵션을 통해 달라지는 부분을 확인할 수 있다.즉 enable_thinking 이 false 인 경우 reasoning 이 없는 reasoning 파트를 assistant indicator 뒤에 강제로 붙여 넣어서, reasoning 이 없는 답변을 생성하는 것이다.이는 reasoning 이 assistant indicator 바로 뒤부터 시작한다는 점을 활용한 것인데, 개인적으로 굉장히 스마트하면서 강력한 방법이라고 생각한다.Qwen3 는 두 가지 방법으로 Hybrid thinking mode 를 구현하였다.첫 번째 방법인 , 명령어는 유저가 API 를 사용하거나 chat 서비스를 활용할 때 명시적으로 제어할 수 있는 방법이지만,학습을 통해 구현되는 것이기 때문에 실제로 를 사용하더라도 reasoning 을 할 가능성이 있다 (확률적으로는 낮겠지만, 어디까지나 가능성은 있다).반면 두 번째 방법인 은 빈 thinking 부분을 강제로 붙여버림으로써 reasoning 을 강력하게 꺼버리는 방법이다아무튼 두 방법 모두 아주 간단하면서도 스마트하게 hybrid think mode 를 구현하였다.이후 모델 학습에 참고해서 사용해 봐야겠다.
5/9/2025
logo
Qwen3 의 Hybrid thinking mode
2025년 4월 29일 새벽에 Alibaba의 Qwen3 가 릴리즈되었다.Technical report 가 공개되지 않고, 블로그로만 공개되었기 때문에 학습이 어떻게 이루어졌는지는 아주 제한적으로 공개되었다.모델은 총 6개로 MoE 모델 2개와 Dense 모델 6개로 구성되었다.MoE 모델은 235B (22B activate), 30B (3B activate), Dense 모델은 32B, 14B, 8B, 4B, 1.7B, 0.6B 의 사이즈다.블로그 글에 따르면 각각 가장 큰 모델만 학습한 뒤, strong-to-weak distillation 을 통해 나머지 모델들을 학습한 것으로 보인다.아마도 base model 들은 pruning 기법들을 통해서 사이즈를 줄인 것 같다. (예상컨데 절반정도씩 줄여나간 것이 아닐까 싶다)사실 technical report 가 공개되지 않아서 학습 방법에 대해서는 아직 확실하게 파악하기 어렵다.그러나 공개된 것 중에 흥미로운 부분이 있었는데, 바로 Hybrid Thinking mode 이라는 것이다.Qwen3 공식 블로그에 따르면 Qwen3 는 thinking, 그러니까 reasoning 이 필요한 어려운 문제나 정확도를 요구하는 task 를 해결할 때에는 test-time reasoning 을 사용하고,빠르게 답변이 필요한 경우에는 think 를 끄고 그냥 답변을 제공하도록 학습되었다.이는 Claude-sonnet-3.7 에서 처음으로 제공했던 방식인데, 내가 알기로 명시적으로 open-source 에서 이를 가능하게 한 것은 처음이다.그렇다면 어떻게 on/off 를 구현했는가? Qwen3 는 두 가지 방법으로 on/off 를 제어하고 있다.유저나 시스템 턴에 , 명령어를 명시적으로 사용하면 thinking 을 제어할 수 있다. 예시를 살펴보자.이에 대한 답변은그리고 옵션 사용한 경우에는이에 대한 답변은, 토큰을 사용하여 reasoning 을 하고, 최종 답변하는 것을 볼 수 있다.아마도 이는 학습 시 thinking 없는 데이터는 를, 있는 데이터는 을 사용하여 학습한 것으로 보인다.즉, 스위치 토큰을 학습에 사용하여, reasoning On/Off 를 제어하는 방법이라고 볼 수 있다.또 다른 방법은 이라는 파라미터를 사용하는 것이다. Qwen3 블로그를 보면 아래와 같은 방법이 나와 있다.과연 옵션을 주면 무엇이 달라지는 것일까?을 보면 Qwen3 의 chat_template 이 있다. 여기서 해당 옵션을 통해 달라지는 부분을 확인할 수 있다.즉 enable_thinking 이 false 인 경우 reasoning 이 없는 reasoning 파트를 assistant indicator 뒤에 강제로 붙여 넣어서, reasoning 이 없는 답변을 생성하는 것이다.이는 reasoning 이 assistant indicator 바로 뒤부터 시작한다는 점을 활용한 것인데, 개인적으로 굉장히 스마트하면서 강력한 방법이라고 생각한다.Qwen3 는 두 가지 방법으로 Hybrid thinking mode 를 구현하였다.첫 번째 방법인 , 명령어는 유저가 API 를 사용하거나 chat 서비스를 활용할 때 명시적으로 제어할 수 있는 방법이지만,학습을 통해 구현되는 것이기 때문에 실제로 를 사용하더라도 reasoning 을 할 가능성이 있다 (확률적으로는 낮겠지만, 어디까지나 가능성은 있다).반면 두 번째 방법인 은 빈 thinking 부분을 강제로 붙여버림으로써 reasoning 을 강력하게 꺼버리는 방법이다아무튼 두 방법 모두 아주 간단하면서도 스마트하게 hybrid think mode 를 구현하였다.이후 모델 학습에 참고해서 사용해 봐야겠다.
2025.05.09
emoji
좋아요
emoji
별로에요
logo
코드 품질 개선 기법 10편: 적절한 거리 유지에 신경 쓰자
안녕하세요. 커뮤니케이션 앱 LINE의 모바 일 클라이언트를 개발하고 있는 Ishikawa입니다.저희 회사는 높은 개발 생산성을 유지하기 위해 코드 품질 및 개발 문화 개선에 힘쓰고 있습니다. 이를 위해 다양한 노력을 하고 있는데요. 그중 하나가 Review Committee 활동입니다.Review Committee에서는 머지된 코드를 다시 리뷰해 리뷰어와 작성자에게 피드백을 주고, 리뷰하면서 얻은 지식과 인사이트를 Weekly Report라는 이름으로 매주 공유하고 있습니다. 이 Weekly Report 중 일반적으로 널리 적용할 수 있는 주제를 골라 블로그에 코드 품질 개선 기법 시리즈를 연재하고 있습니다.이번에 블로그로 공유할 Weekly Report의 제목은 '적절한 거리 유지에 신경 쓰자'입니다.정렬된 목록을 표시하는 UI를 구현한다고 가정해 봅시다. 이 목록 상단에는 의 총 개수를 표시하는 헤더가 있습니다. 다음은 목록 표시 예시입니다.목록 및 총 개수 표시에는 다음과 같은 사양이 있습니다.• 목록에 표시할 수 있는 개수는 처음 100개까지• 100 개를 초과하는 이 있는 경우 총 개수는 "100+"로 표시총 개수가 100을 초과할 때 표시 형식은 다음과 같습니다.이 사양을 구현하기 위해 모델 클래 스 과 및 를 다음과 같이 정의했습니다.한편 UI에서 총 개수를 표시하는 텍스트를 결정하는 로직은 개수가 를 초과하는지 아닌지에 따라 분기됩니다.이 코드에 문제가 있을까요?'+1'만큼의 거리를 유지하자코드를 여러 레이어나 컴포넌트로 나눌 때에는 '어떤 레이어나 컴포넌트가 어떤 정보를 가져야 하는지'를 고려해서 설계하는 것이 좋습니다. 하지만 위 코드는 UI와 리포지터리 레이어 간에 '암묵적인 정보'를 공유하고 있기 때문에 사양을 변경했을 때 버그가 발생하기 쉬운 구조입니다.구체적으로 살펴보겠습니다. 먼저 리포지터리 레이어는 UI의 세부 사항에 대해 알 필요가 없는데요. 라는 주석은 이에 반해 세부 사항을 알리고 있습니다.반대로 UI 측도 리포지터리 레 이어의 세부 사항에 의존하고 있습니다. UI 측에서 를 구하는 로직이 리포지터리 레이어의 ' 를 초과하는 이 있을 경우 보다 큰 목록을 반환한다'는 동작에 의존하고 있기 때문입니다.이 문제를 해결하기 위해서는 다음과 같이 '목록에 다 들어갈 수 없는 이 있는지'를 나타내는 속성을 에 추가하면 됩니다.이렇게 하면 리포지터리 레이어는 UI 세부 사항을 신경 쓰지 않고 모델 클래스의 인스턴스 생성에 집중할 수 있습니다.또한 UI 레이어는 더 이상 에 대한 정보가 없어도 됩니다.그런데 ITEM_LIST_MAX_COUNT는 리포지터리 레이어에 있어도 괜찮을까?관련 정보를 어디에 넣을지에 대해서는 몇 가지 선택지가 있습니다.예를 들어 비즈니스 로직 레이어를 마련하고 그곳에서 를 정의할 수 있습니다. 비즈니스 로직 레이어는 채택하는 아키텍처에 따라 도메인, 서비스, 유스 케이스 등 다양한 형태가 될 수 있습니다.만약 비즈니스 로직 레이어를 만드는 것이 과하다고 생각한다면 모델 클래스에 해당 정보를 넣는 것도 한 가지 방법입니다.다만 이 방법은 '알고리즘 -> 데이터 구조'라는 의존 관계의 방향이 모호해지기 때문에 주의해야 합니다. 특히 기능 고유의 로직을 범용적으로 사용되는 데이터 모델에 포함시키지 않도록 조심해야 합니다.
5/9/2025
logo
코드 품질 개선 기법 10편: 적절한 거리 유지에 신경 쓰자
안녕하세요. 커뮤니케이션 앱 LINE의 모바 일 클라이언트를 개발하고 있는 Ishikawa입니다.저희 회사는 높은 개발 생산성을 유지하기 위해 코드 품질 및 개발 문화 개선에 힘쓰고 있습니다. 이를 위해 다양한 노력을 하고 있는데요. 그중 하나가 Review Committee 활동입니다.Review Committee에서는 머지된 코드를 다시 리뷰해 리뷰어와 작성자에게 피드백을 주고, 리뷰하면서 얻은 지식과 인사이트를 Weekly Report라는 이름으로 매주 공유하고 있습니다. 이 Weekly Report 중 일반적으로 널리 적용할 수 있는 주제를 골라 블로그에 코드 품질 개선 기법 시리즈를 연재하고 있습니다.이번에 블로그로 공유할 Weekly Report의 제목은 '적절한 거리 유지에 신경 쓰자'입니다.정렬된 목록을 표시하는 UI를 구현한다고 가정해 봅시다. 이 목록 상단에는 의 총 개수를 표시하는 헤더가 있습니다. 다음은 목록 표시 예시입니다.목록 및 총 개수 표시에는 다음과 같은 사양이 있습니다.• 목록에 표시할 수 있는 개수는 처음 100개까지• 100 개를 초과하는 이 있는 경우 총 개수는 "100+"로 표시총 개수가 100을 초과할 때 표시 형식은 다음과 같습니다.이 사양을 구현하기 위해 모델 클래 스 과 및 를 다음과 같이 정의했습니다.한편 UI에서 총 개수를 표시하는 텍스트를 결정하는 로직은 개수가 를 초과하는지 아닌지에 따라 분기됩니다.이 코드에 문제가 있을까요?'+1'만큼의 거리를 유지하자코드를 여러 레이어나 컴포넌트로 나눌 때에는 '어떤 레이어나 컴포넌트가 어떤 정보를 가져야 하는지'를 고려해서 설계하는 것이 좋습니다. 하지만 위 코드는 UI와 리포지터리 레이어 간에 '암묵적인 정보'를 공유하고 있기 때문에 사양을 변경했을 때 버그가 발생하기 쉬운 구조입니다.구체적으로 살펴보겠습니다. 먼저 리포지터리 레이어는 UI의 세부 사항에 대해 알 필요가 없는데요. 라는 주석은 이에 반해 세부 사항을 알리고 있습니다.반대로 UI 측도 리포지터리 레 이어의 세부 사항에 의존하고 있습니다. UI 측에서 를 구하는 로직이 리포지터리 레이어의 ' 를 초과하는 이 있을 경우 보다 큰 목록을 반환한다'는 동작에 의존하고 있기 때문입니다.이 문제를 해결하기 위해서는 다음과 같이 '목록에 다 들어갈 수 없는 이 있는지'를 나타내는 속성을 에 추가하면 됩니다.이렇게 하면 리포지터리 레이어는 UI 세부 사항을 신경 쓰지 않고 모델 클래스의 인스턴스 생성에 집중할 수 있습니다.또한 UI 레이어는 더 이상 에 대한 정보가 없어도 됩니다.그런데 ITEM_LIST_MAX_COUNT는 리포지터리 레이어에 있어도 괜찮을까?관련 정보를 어디에 넣을지에 대해서는 몇 가지 선택지가 있습니다.예를 들어 비즈니스 로직 레이어를 마련하고 그곳에서 를 정의할 수 있습니다. 비즈니스 로직 레이어는 채택하는 아키텍처에 따라 도메인, 서비스, 유스 케이스 등 다양한 형태가 될 수 있습니다.만약 비즈니스 로직 레이어를 만드는 것이 과하다고 생각한다면 모델 클래스에 해당 정보를 넣는 것도 한 가지 방법입니다.다만 이 방법은 '알고리즘 -> 데이터 구조'라는 의존 관계의 방향이 모호해지기 때문에 주의해야 합니다. 특히 기능 고유의 로직을 범용적으로 사용되는 데이터 모델에 포함시키지 않도록 조심해야 합니다.
2025.05.09
emoji
좋아요
emoji
별로에요
logo
FE News 25년 5월 소식을 전해드립니다!
주요내용25년 5월 소식에서는 다음과 같은 유용한 정보들을 만나보실 수 있습니다.React Compiler RCuseMemo 없이도 성능 최적화를 자동으로 처리해주는 새로운 리액트 컴파일러가 드디어 RC 단계에 도달했다.proposal-record-tuple is withdrawn값 기반 데이터 구조 도입을 목표로 했던 R&T가 철회되고, 더 유연한 대안인 Composite 제안이 새롭게 부상 중이다.Features That Every JavaScript Developer Must Know in 2025알아두면 실무에서 바로 쓸 수 있는 JS 기능들을 사례와 함께 정리한다.LLM-first Web FrameworkLLM이 이해하고 생성하기 쉬운 웹 코드를 위해, 정적·동적 값을 동일하게 다루는 프레임워크를 Revolt 기반으로 설계한 사례를 소개한다.>> FE News 25년 5월 소식 보러가기 FE News란? 네이버 FE 엔지니어들이 엄선한 양질의 FE 및 주요한 기술 소식들을 큐레이션해 공유하는 것을 목표로 하며, 이를 통해 국내 개발자들에게 지식 공유에 대한 가치 인식과 성장에 도움을 주고자 하는 기술소식 공유 프로젝트 입니다. 매월 첫째 주 수요일, 월 1회 발행 되고 있으니 많은 관심 부탁드립니다. 구독하기
5/8/2025
logo
FE News 25년 5월 소식을 전해드립니다!
주요내용25년 5월 소식에서는 다음과 같은 유용한 정보들을 만나보실 수 있습니다.React Compiler RCuseMemo 없이도 성능 최적화를 자동으로 처리해주는 새로운 리액트 컴파일러가 드디어 RC 단계에 도달했다.proposal-record-tuple is withdrawn값 기반 데이터 구조 도입을 목표로 했던 R&T가 철회되고, 더 유연한 대안인 Composite 제안이 새롭게 부상 중이다.Features That Every JavaScript Developer Must Know in 2025알아두면 실무에서 바로 쓸 수 있는 JS 기능들을 사례와 함께 정리한다.LLM-first Web FrameworkLLM이 이해하고 생성하기 쉬운 웹 코드를 위해, 정적·동적 값을 동일하게 다루는 프레임워크를 Revolt 기반으로 설계한 사례를 소개한다.>> FE News 25년 5월 소식 보러가기 FE News란? 네이버 FE 엔지니어들이 엄선한 양질의 FE 및 주요한 기술 소식들을 큐레이션해 공유하는 것을 목표로 하며, 이를 통해 국내 개발자들에게 지식 공유에 대한 가치 인식과 성장에 도움을 주고자 하는 기술소식 공유 프로젝트 입니다. 매월 첫째 주 수요일, 월 1회 발행 되고 있으니 많은 관심 부탁드립니다. 구독하기
2025.05.08
emoji
좋아요
emoji
별로에요
logo
Reasoning 모델 기반의 AI 검색 고도화
안녕하세요. SK텔레콤에서 검색/추천 모델링을 담당하고 있는 김선겸입니다.오늘 Reasoning 모델 기반의 AI 검색 고도화의 주제로 이야기 해 보려고 합니다.AI 검색 이전에는 주로 키워드 매칭이나 임베딩 기반 벡터 유사도를 기반으로 Relevance Score가 높은 Top-N 결과를 사용자에게 제시하는 방식으로 정보를 제공해 왔습니다.이 접근 방식은 빠르고 효율적인 검색을 가능하게 했지만, 질문의 의도나 문맥에 대한 이해가 부족해 사용자가 직접 결과를 해석하고 선택해야 하는 한계를 지니고 있었습니다.특히 복잡한 정보의 연결이나 다단계 추론이 필요한 고차원 질의에서는 이러한 방식의 한계가 더욱 뚜렷하게 드러납니다.이러한 한계를 극복하고자 최근에는 Reasoning 능력을 내재한 대형 언어 모델이 검색 시스템에 통합되고 있습니다.단순히 관련 정보를 나열하는 데 그치지 않고, 사용자의 질문을 단계적으로 분석하고 논리적으로 사고하여최종 답변을 직접 도출하거나 보다 명확한 정보로 정리해 제시하는 형태로 진화하고 있는 것입니다.이번 글에서는 Reasoning 모델의 핵심 개념과 주요 특징을 살펴본 뒤, 대표적인 추론 방식인 Chain-of-Thought(CoT)의 활용법과 이를 기반으로 한 모델 학습 과정에 대해 소개합니다.또한 이러한 Reasoning 기반 언어 모델이 실제 SKT AI 검색 시스템과 어떻게 결합되어 고도화를 이끌고 있는지도 함께 살펴보겠습니다.전통적인 대형 언어 모델(LLM)들이 문맥을 기반으로 한 언어 생성 및 예측에 집중했던 것과 달리,Reasoning 모델은 문제 해결 과정에서 인간의 사고 과정을 모방하여, 더 깊고 체계적인 사고를 가능하게 합니다.Reasoning 모델의 핵심 개념과 특징에 대해 알아보도록 하겠습니다.• None• None CoT는 문제를 한 번에 해결하려고 시도하는 대신, 이를 여러 하위 단계로 세분화하여 단계별로 사고 과정을 전개해 나가는 방식입니다. 이 기법은 모델이 각 단계에서 중간 추론을 명시적으로 수행하게 유도함으로써, 복잡한 문제라도 보다 체계적이고 논리적으로 접근할 수 있도록 만듭니다. 결과적으로 CoT를 적용하면 모델이 인간처럼 "생각을 풀어가는 과정"을 모방하며, 최종 결론에 도달하는 과정을 투명하게 보여줄 수 있습니다.• None ToT는 사고 과정을 단일 경로로 제한하지 않고, 여러 가능한 추론 경로를 동시에 생성하여 탐색하는 접근 방식입니다. 문제 해결을 위해 다양한 가설이나 방법을 고려하고, 각각의 경로를 평가하면서 가장 합리적이고 타당한 답을 선택하는 전략을 취합니다. 이 과정에서 비효율적이거나 부정확한 경로는 가지치기(pruning)하고, 유망한 경로는 더욱 깊게 탐색해 나갑니다. ToT는 CoT보다 훨씬 더 복잡하고 다양한 가능성을 포괄할 수 있으며, 특히 경로 선택이나 탐색 최적화가 중요한 문제 상황에서 강력한 성능을 발휘합니다.• None• None Reasoning 모델은 복잡한 수학 문제, 논리적 추론, 코딩 문제처럼 단일 답변 생성만으로는 쉽게 해결할 수 없는 과제들에 대해 탁월한 성능을 발휘합니다. 이 모델은 문제를 해결하는 과정에서 단계별 사고 과정을 명시적으로 노출함으로써, 단순한 정답 예측을 넘어 보다 깊이 있고 신뢰성 있는 문제 해결을 가능하게 만듭니다. 특히 Reasoning 모델은 다음과 같은 주요 장점을 가지고 있습니다• None Reasoning 모델은 문제를 여러 단계로 분해하고 각 단계에서 검증 가능한 추론을 거치기 때문에, 전체적인 오답률이 크게 낮아집니다. 단순히 직관에 의존하는 답변보다, 체계적으로 축적된 추론을 기반으로 한 답변이기 때문에 정확성이 한층 강화됩니다.• None 모델이 사고 과정을 외부에 투명하게 드러내기 때문에, 사용자는 답변이 어떻게 도출되었는지 구체적인 설명을 확인할 수 있습니다. 이러한 해석 가능성은 특히 고신뢰가 요구되는 분야(예: 의료, 법률, 과학)에서 모델의 활용 가치를 크게 높여줍니다.• None Reasoning 모델은 문제 해결의 각 단계를 점검하는 구조를 가지고 있어, 중간 추론 과정에서 발생할 수 있는 오류나 비현실적인 답변 생성(일명 "환각(hallucination)" 현상)을 줄이는 데 매우 효과적입니다. 이를 통해 모델의 답변 신뢰성과 일관성이 한층 강화됩니다. 결국, Reasoning 모델은 단순 정답 생성 모델을 넘어, "왜"라는 질문에 답할 수 있는 설명력과, 복잡한 문제를 다루는 데 필요한 높은 정확도와 안정성을 함께 제공하는 방향으로 진화하고 있습니다.• None• None 대부분의 벤치마크 결과에서 DeepSeek-R1(Reasoning 모델)이 DeepSeek-V3(Non-Reasoning 모델) 대비 더 높은 성능을 보이는 것을 확인할 수 있습니다. 특히 AIME 2024, Codeforces, GPQA Diamond와 같은 벤치마크에서는 두 모델 간 성능 차이가 두드러지게 나타납니다. 이러한 결과는 수학, 과학, 프로그래밍처럼 추론이 요구되는 도메인에서 Reasoning 모델이 더욱 효과적임을 보여줍니다. 다만, 일부 벤치마크에서는 DeepSeek-R1의 성능이 더 높긴 하지만 그 차이가 크지 않은 경우도 관찰됩니다.• None 비용 효율성과 추론 속도 측면에서 우수한 GPT-4o mini와 GPT-o3-mini를 비교한 결과는 위와 같습니다. 두 모델은 아키텍처와 파라미터 규모에서 차이가 있기 때문에 절대적으로 공정한 비교는 어렵지만, Reasoning 특화 모델인 GPT-o3-mini는 전반적인 성능 면에서 우위를 보였습니다. 특히 수학, 논리, 코드 생성 등 고차원 추론이 요구되는 과제에서는 성능 격차가 더욱 명확하게 드러났습니다.• None GPT-4o mini의 상대적으로 낮은 성능을 고려하여, 동일 계열의 상위 모델인 GPT-4o와 성능을 비교해보았습니다. 그 결과, AIME 및 Codeforces와 같은 고난도 추론 중심의 벤치마크에서는 두 모델 간 성능 차이가 뚜렷하게 나타났으며, 반면 MMLU나 Simple QA처럼 비교적 단순한 언어 이해 과제에서는 GPT-4o mini가 오히려 더 우수한
5/8/2025
logo
Reasoning 모델 기반의 AI 검색 고도화
안녕하세요. SK텔레콤에서 검색/추천 모델링을 담당하고 있는 김선겸입니다.오늘 Reasoning 모델 기반의 AI 검색 고도화의 주제로 이야기 해 보려고 합니다.AI 검색 이전에는 주로 키워드 매칭이나 임베딩 기반 벡터 유사도를 기반으로 Relevance Score가 높은 Top-N 결과를 사용자에게 제시하는 방식으로 정보를 제공해 왔습니다.이 접근 방식은 빠르고 효율적인 검색을 가능하게 했지만, 질문의 의도나 문맥에 대한 이해가 부족해 사용자가 직접 결과를 해석하고 선택해야 하는 한계를 지니고 있었습니다.특히 복잡한 정보의 연결이나 다단계 추론이 필요한 고차원 질의에서는 이러한 방식의 한계가 더욱 뚜렷하게 드러납니다.이러한 한계를 극복하고자 최근에는 Reasoning 능력을 내재한 대형 언어 모델이 검색 시스템에 통합되고 있습니다.단순히 관련 정보를 나열하는 데 그치지 않고, 사용자의 질문을 단계적으로 분석하고 논리적으로 사고하여최종 답변을 직접 도출하거나 보다 명확한 정보로 정리해 제시하는 형태로 진화하고 있는 것입니다.이번 글에서는 Reasoning 모델의 핵심 개념과 주요 특징을 살펴본 뒤, 대표적인 추론 방식인 Chain-of-Thought(CoT)의 활용법과 이를 기반으로 한 모델 학습 과정에 대해 소개합니다.또한 이러한 Reasoning 기반 언어 모델이 실제 SKT AI 검색 시스템과 어떻게 결합되어 고도화를 이끌고 있는지도 함께 살펴보겠습니다.전통적인 대형 언어 모델(LLM)들이 문맥을 기반으로 한 언어 생성 및 예측에 집중했던 것과 달리,Reasoning 모델은 문제 해결 과정에서 인간의 사고 과정을 모방하여, 더 깊고 체계적인 사고를 가능하게 합니다.Reasoning 모델의 핵심 개념과 특징에 대해 알아보도록 하겠습니다.• None• None CoT는 문제를 한 번에 해결하려고 시도하는 대신, 이를 여러 하위 단계로 세분화하여 단계별로 사고 과정을 전개해 나가는 방식입니다. 이 기법은 모델이 각 단계에서 중간 추론을 명시적으로 수행하게 유도함으로써, 복잡한 문제라도 보다 체계적이고 논리적으로 접근할 수 있도록 만듭니다. 결과적으로 CoT를 적용하면 모델이 인간처럼 "생각을 풀어가는 과정"을 모방하며, 최종 결론에 도달하는 과정을 투명하게 보여줄 수 있습니다.• None ToT는 사고 과정을 단일 경로로 제한하지 않고, 여러 가능한 추론 경로를 동시에 생성하여 탐색하는 접근 방식입니다. 문제 해결을 위해 다양한 가설이나 방법을 고려하고, 각각의 경로를 평가하면서 가장 합리적이고 타당한 답을 선택하는 전략을 취합니다. 이 과정에서 비효율적이거나 부정확한 경로는 가지치기(pruning)하고, 유망한 경로는 더욱 깊게 탐색해 나갑니다. ToT는 CoT보다 훨씬 더 복잡하고 다양한 가능성을 포괄할 수 있으며, 특히 경로 선택이나 탐색 최적화가 중요한 문제 상황에서 강력한 성능을 발휘합니다.• None• None Reasoning 모델은 복잡한 수학 문제, 논리적 추론, 코딩 문제처럼 단일 답변 생성만으로는 쉽게 해결할 수 없는 과제들에 대해 탁월한 성능을 발휘합니다. 이 모델은 문제를 해결하는 과정에서 단계별 사고 과정을 명시적으로 노출함으로써, 단순한 정답 예측을 넘어 보다 깊이 있고 신뢰성 있는 문제 해결을 가능하게 만듭니다. 특히 Reasoning 모델은 다음과 같은 주요 장점을 가지고 있습니다• None Reasoning 모델은 문제를 여러 단계로 분해하고 각 단계에서 검증 가능한 추론을 거치기 때문에, 전체적인 오답률이 크게 낮아집니다. 단순히 직관에 의존하는 답변보다, 체계적으로 축적된 추론을 기반으로 한 답변이기 때문에 정확성이 한층 강화됩니다.• None 모델이 사고 과정을 외부에 투명하게 드러내기 때문에, 사용자는 답변이 어떻게 도출되었는지 구체적인 설명을 확인할 수 있습니다. 이러한 해석 가능성은 특히 고신뢰가 요구되는 분야(예: 의료, 법률, 과학)에서 모델의 활용 가치를 크게 높여줍니다.• None Reasoning 모델은 문제 해결의 각 단계를 점검하는 구조를 가지고 있어, 중간 추론 과정에서 발생할 수 있는 오류나 비현실적인 답변 생성(일명 "환각(hallucination)" 현상)을 줄이는 데 매우 효과적입니다. 이를 통해 모델의 답변 신뢰성과 일관성이 한층 강화됩니다. 결국, Reasoning 모델은 단순 정답 생성 모델을 넘어, "왜"라는 질문에 답할 수 있는 설명력과, 복잡한 문제를 다루는 데 필요한 높은 정확도와 안정성을 함께 제공하는 방향으로 진화하고 있습니다.• None• None 대부분의 벤치마크 결과에서 DeepSeek-R1(Reasoning 모델)이 DeepSeek-V3(Non-Reasoning 모델) 대비 더 높은 성능을 보이는 것을 확인할 수 있습니다. 특히 AIME 2024, Codeforces, GPQA Diamond와 같은 벤치마크에서는 두 모델 간 성능 차이가 두드러지게 나타납니다. 이러한 결과는 수학, 과학, 프로그래밍처럼 추론이 요구되는 도메인에서 Reasoning 모델이 더욱 효과적임을 보여줍니다. 다만, 일부 벤치마크에서는 DeepSeek-R1의 성능이 더 높긴 하지만 그 차이가 크지 않은 경우도 관찰됩니다.• None 비용 효율성과 추론 속도 측면에서 우수한 GPT-4o mini와 GPT-o3-mini를 비교한 결과는 위와 같습니다. 두 모델은 아키텍처와 파라미터 규모에서 차이가 있기 때문에 절대적으로 공정한 비교는 어렵지만, Reasoning 특화 모델인 GPT-o3-mini는 전반적인 성능 면에서 우위를 보였습니다. 특히 수학, 논리, 코드 생성 등 고차원 추론이 요구되는 과제에서는 성능 격차가 더욱 명확하게 드러났습니다.• None GPT-4o mini의 상대적으로 낮은 성능을 고려하여, 동일 계열의 상위 모델인 GPT-4o와 성능을 비교해보았습니다. 그 결과, AIME 및 Codeforces와 같은 고난도 추론 중심의 벤치마크에서는 두 모델 간 성능 차이가 뚜렷하게 나타났으며, 반면 MMLU나 Simple QA처럼 비교적 단순한 언어 이해 과제에서는 GPT-4o mini가 오히려 더 우수한
2025.05.08
emoji
좋아요
emoji
별로에요
logo
NVIDIA GPU Operator로 GPU 모니터링 PoC 구축하기
GPU를 활용한 클라우드 환경에서는 비용 효율적이고 안정적인 운영을 위해 GPU 자원의 성능 지표(Metric)를 정확하게 수집하고 분석할 수 있는 모니터링 시스템 구축이 필수적입니다.특히 GPU 인스턴스는 높은 성능만큼 비용도 상대적으로 높아 효율적인 자원 관리와 비용 최적화가 매우 중요합니다.본 글에서는 이러한 과제를 해결하기 위해 AWS의 GPU 스팟(Spot) 인스턴스(g4dn, g5, g6)를 기반으로 Kubernetes(EKS) NodeGroup을 구성하고,NVIDIA GPU Operator를 통해 GPU 자원을 모니터링하는 PoC(Proof of Concept) 환경을 구축하는 방법을 소개합니다.스팟 인스턴스는 온디맨드 인스턴스 대비 약 70~80%까지 비용을 절감할 수 있지만,모든 리전 및 가용영역(AZ)에서 사용할 수 있는 것은 아니므로, 사전에 각 인스턴스 타입의 비용과 가용성을 확인하는 것이 중요합니다.본 가이드에서는 다음과 같은 작업을 진행하겠습니다.• None AWS에서 GPU 스팟 인스턴스를 이용한 EKS 클러스터 및 NodeGroup 구성이 글을 통해 GPU 기반 클라우드 자원의 효율적인 관리 방안을 확인하고, 비용 효율성을 높이는 실질적인 방법을 익힐 수 있습니다.AWS에서 GPU 스팟 인스턴스를 이용한 EKS 클러스터 및 NodeGroup 구성K8s 클러스터를 생성하기 위해 필수적인 정보를 입력한 cluster.yaml 파일을 생성합니다.eksctl 명령어를 이용하여 K8s 클러스터를 생성합니다.성공적으로 구성이 완료되었다면, 다음 명령어를 통해 kubeconfig를 업데이트하고 노드를 조회합니다.NVIDIA GPU Operator는 Kubernetes 환경에서 GPU 자원을 효율적으로 관리할 수 있도록 지원하는 오픈소스 솔루션입니다.GPU Operator는 NVIDIA 드라이버 설치부터, GPU 자원 할당 및 관리, 성능 모니터링까지의 전체 과정을 자동화합니다.이를 통해 GPU 기반 워크로드의 배포와 관리가 쉬워지고, 운영 효율성을 높일 수 있습니다.• None NVIDIA GPU 드라이버의 자동 설치 및 관리GPU Operator는 Helm을 사용하여 Kubernetes 클러스터에 쉽게 설치할 수 있습니다. 아래와 같은 순서로 진행합니다:모든 Pod가 정상적으로 실행되고 있으면 설치가 성공적으로 완료된 것입니다.Prometheus는 Kubernetes 환경에서 메트릭을 수집하고 저장하는 대표적인 모니터링 시스템입니다.Grafana는 수집된 메트릭을 시각화하여 분석할 수 있게 지원합니다.본 글에서는 Prometheus와 Grafana를 Helm을 사용하여 설치하는 방법을 안내합니다.브라우저에서 http://localhost:9090 으로 접속할 수 있습니다.DCGM 메트릭을 입력하여 정상적으로 조회되는지 확인합니다.Prometheus 로 수집된 메트릭을 시각적으로 확인하기 위해서 Grafana 대시보드를 사용합니다.메트릭에 따라 사전에 정의된 대시보드가 있으며 Grafana 공식사이트에서 조회 후 대시보드 ID를 복사하여 사용하거나, 기존에 사용하는 대시보드를 json 파일로 등록할 수 있습니다.대시보드 ID를 클립보드에 복사합니다.배포한 Grafana에 접속하여 복사한 대시보드 ID를 로드합니다.Grafana에서 NVIDIA DCGM Exporter Dashboard를 가져오면 GPU 사용률, 전력 소비량, 메모리 사용량 등을 시각화할 수 있습니다.값이 조회되지 않는 경우에는 편집 모드로 변경 후 Metrics browser의 메트릭 값을 복사하여 Prometheus 콘솔에서 조회되는지 확인합니다.이제 AWS GPU 인스턴스 환경에서 NVIDIA GPU Operator를 활용하여 GPU 자원 모니터링이 가능합니다.Kubernetes 환경에 구축된 Prometheus와 Grafana를 통해 GPU 성능 데이터를 실시간으로 수집하고 분석할 수 있습니다.본 글에서 구축한 환경은 클라우드뿐만 아니라 On-Premise 환경에서도 활용 가능하며, 이를 통해 GPU 자원의 최적화와 운영 비용의 효율적 관리가 가능합니다.
grafana
kubernetes
prometheus
5/7/2025
logo
NVIDIA GPU Operator로 GPU 모니터링 PoC 구축하기
GPU를 활용한 클라우드 환경에서는 비용 효율적이고 안정적인 운영을 위해 GPU 자원의 성능 지표(Metric)를 정확하게 수집하고 분석할 수 있는 모니터링 시스템 구축이 필수적입니다.특히 GPU 인스턴스는 높은 성능만큼 비용도 상대적으로 높아 효율적인 자원 관리와 비용 최적화가 매우 중요합니다.본 글에서는 이러한 과제를 해결하기 위해 AWS의 GPU 스팟(Spot) 인스턴스(g4dn, g5, g6)를 기반으로 Kubernetes(EKS) NodeGroup을 구성하고,NVIDIA GPU Operator를 통해 GPU 자원을 모니터링하는 PoC(Proof of Concept) 환경을 구축하는 방법을 소개합니다.스팟 인스턴스는 온디맨드 인스턴스 대비 약 70~80%까지 비용을 절감할 수 있지만,모든 리전 및 가용영역(AZ)에서 사용할 수 있는 것은 아니므로, 사전에 각 인스턴스 타입의 비용과 가용성을 확인하는 것이 중요합니다.본 가이드에서는 다음과 같은 작업을 진행하겠습니다.• None AWS에서 GPU 스팟 인스턴스를 이용한 EKS 클러스터 및 NodeGroup 구성이 글을 통해 GPU 기반 클라우드 자원의 효율적인 관리 방안을 확인하고, 비용 효율성을 높이는 실질적인 방법을 익힐 수 있습니다.AWS에서 GPU 스팟 인스턴스를 이용한 EKS 클러스터 및 NodeGroup 구성K8s 클러스터를 생성하기 위해 필수적인 정보를 입력한 cluster.yaml 파일을 생성합니다.eksctl 명령어를 이용하여 K8s 클러스터를 생성합니다.성공적으로 구성이 완료되었다면, 다음 명령어를 통해 kubeconfig를 업데이트하고 노드를 조회합니다.NVIDIA GPU Operator는 Kubernetes 환경에서 GPU 자원을 효율적으로 관리할 수 있도록 지원하는 오픈소스 솔루션입니다.GPU Operator는 NVIDIA 드라이버 설치부터, GPU 자원 할당 및 관리, 성능 모니터링까지의 전체 과정을 자동화합니다.이를 통해 GPU 기반 워크로드의 배포와 관리가 쉬워지고, 운영 효율성을 높일 수 있습니다.• None NVIDIA GPU 드라이버의 자동 설치 및 관리GPU Operator는 Helm을 사용하여 Kubernetes 클러스터에 쉽게 설치할 수 있습니다. 아래와 같은 순서로 진행합니다:모든 Pod가 정상적으로 실행되고 있으면 설치가 성공적으로 완료된 것입니다.Prometheus는 Kubernetes 환경에서 메트릭을 수집하고 저장하는 대표적인 모니터링 시스템입니다.Grafana는 수집된 메트릭을 시각화하여 분석할 수 있게 지원합니다.본 글에서는 Prometheus와 Grafana를 Helm을 사용하여 설치하는 방법을 안내합니다.브라우저에서 http://localhost:9090 으로 접속할 수 있습니다.DCGM 메트릭을 입력하여 정상적으로 조회되는지 확인합니다.Prometheus 로 수집된 메트릭을 시각적으로 확인하기 위해서 Grafana 대시보드를 사용합니다.메트릭에 따라 사전에 정의된 대시보드가 있으며 Grafana 공식사이트에서 조회 후 대시보드 ID를 복사하여 사용하거나, 기존에 사용하는 대시보드를 json 파일로 등록할 수 있습니다.대시보드 ID를 클립보드에 복사합니다.배포한 Grafana에 접속하여 복사한 대시보드 ID를 로드합니다.Grafana에서 NVIDIA DCGM Exporter Dashboard를 가져오면 GPU 사용률, 전력 소비량, 메모리 사용량 등을 시각화할 수 있습니다.값이 조회되지 않는 경우에는 편집 모드로 변경 후 Metrics browser의 메트릭 값을 복사하여 Prometheus 콘솔에서 조회되는지 확인합니다.이제 AWS GPU 인스턴스 환경에서 NVIDIA GPU Operator를 활용하여 GPU 자원 모니터링이 가능합니다.Kubernetes 환경에 구축된 Prometheus와 Grafana를 통해 GPU 성능 데이터를 실시간으로 수집하고 분석할 수 있습니다.본 글에서 구축한 환경은 클라우드뿐만 아니라 On-Premise 환경에서도 활용 가능하며, 이를 통해 GPU 자원의 최적화와 운영 비용의 효율적 관리가 가능합니다.
2025.05.07
grafana
kubernetes
prometheus
emoji
좋아요
emoji
별로에요
logo
내가 JUnit5에 병렬화를 도입한 이야기 - 메서드 단위
안녕하세요, Junit-team/junit5, spring/spring-boot, apache/seata, naver/fixture-monkey 등 여러 오픈소스 프로젝트에 기여한 YongGoose입니다.처음에는 오픈소스 기여에 대한 관심을 높이려는 의도로 글을 쓰기 시작했지만, 점점 나의 소중한 자식들(?)을 소개하는 재미가 생기네요.이번 글은 아래의 글의 후속 편입니다. (미리 읽고 오시면 좋습니다)JUnit5에 병렬화를 도입한 이야기 - 클래스 단위저번 글에서는 JUnit의 Vintage 엔진에 클래스 단위의 병렬화를 도입한 것을 설명했습니다.여러 개의 테스트 클래스를 실행할 때는 해당 기능으로 인해 성능 향상을 기대할 수 있지만,만약 하나의 테스트 클래스에 있는 여러 개의 메서드를 실행할 때는 성능 향상을 기대하기 어렵습니다.그로 인해 메서드 단위의 병렬화도 메인테이너님께 제안을 드렸고, 긍정적인 답변을 받아 작업을 하게 되었습니다.메인테이너님의 코멘트에서 볼 수 있다시피 클래스 단위 병렬화에서 사용하던 스레드 풀을 활용하면 쉽게 해결이 되는 듯했습니다.그래서 위 다이어그램과 같이 Runner가 ParentRunner인 경우, 모든 childStatement(메서드)를 스레드 풀을 활용해 비동기로 실행하도록 구현했습니다.하지만, 제 기대와 달리 교착 상태가 발생하였습니다.위 이미지는 Github Actions의 워크플로우 결과 이미지인데 6시간 동안 실행을 한 뒤, 시간이 초과되어 자동으로 실패한 것을 볼 수 있습니다.이때 교착 상태는 클래스와 메서드에서 모두 병렬화를 활성화시키고, 테스트 클래스의 수보다 스레드 풀의 크기가 작을 때 발생하였습니다.클래스와 메서드 단위에서 병렬화를 모두 활성화시키면 다음과 같은 순서로 실행이 됩니다.이때 교착 상태는 테스트 클래스의 개수보다 스레드 풀의 크기가 작을 때 발생했습니다. (동일할 때도 발생했습니다)자세히 디버깅한 결과, 현재 사용 중인 스레드 풀의 특성과 연관하여 교착 상태가 발생한 원인을 확인할 수 있었습니다.실행 순서 중, 2번(각 상위 작업에 대해 실행 시작)을 할 때 하나의 스레드가 할당이 됩니다.그리고 해당 스레드는 모든 하위 작업이 완료되어 상위 작업이 완료가 되면 스레드가 반환이 됩니다.만약 스레드 풀의 크기가 3이고, 테스트 클래스의 개수가 3, 각 하위 메서드의 개수도 3이라면모든 스레드는 상위 클래스가 점유하게 되어 하위 메서드는 작업 큐에만 저장이 될 뿐 실행이 되지 않아 교착상태가 발생하는 것입니다.교착상태가 일어나는 4가지 조건과 함께 더 자세히 설명드리겠습니다.우선, 교착 상태가 일어나는 4가지 조건은 아래와 같습니다.그러면 현재의 상태에 대입해 설명하겠습니다.• None 상호 배제 : 스레드는 한 번에 하나의 작업만 사용할 수 있습니다.• None 점유 대기 : 상위 작업(클래스)은 각각 스레드를 점유한 상태에서 하위 작업(메서드)을 제출하고 완료를 기다립니다.• None 비선점 : 현재 사용 중인 스레드는 점유된 스레드를 강제로 해제하거나 다른 작업에 재할당 하지 않습니다.• None 순환 대기 : 상위 작업(클래스)은 각각 하위 작업(메서드)의 완료를 기다리고, 하위 작업(메서드)은 상위 작업(클래스)이 완료되어 스레드가 반환되기를 기다리고 있습니다.아래의 그림은 다이어그램으로 설명한 그림입니다. (조금 난잡해 보이더라도 순서대로 읽으시면 잘 이해가 될 거라고 생각합니다...)그래서 메인테이너님과 현재 상황에 대해 토론을 한 결과 ForkJoinPool을 사용하기로 결정이 되었습니다.ForkJoinPool은 작업 큐에 작업이 남아있는 경우 스레드가 블로킹되지 않고 다른 작업을 처리하는 특성을 가지고 있습니다.그래서 교착상태가 발생하는 4가지 조건 중, 순환 대기를 해결할 수 있다는 장점이 있습니다.각각의 작업이 서로의 작업의 완료를 기다리고 있는 상태가 순환 대기인데 ForkJoinPool을 활용하여 서로의 작업의 완료를 기다리지 않고 다른 작업을 처리하도록 구현하였습니다.Jupiter 엔진의 경우 이미 병렬화에서 ForkJoinPool을 사용하고 있었습니다.아래의 코드는 ForkJoinPool을 활용해 교착상태를 해결하고 메서드 단위의 병렬화를 구현한 코드입니다.work stealing을 허용하기 위해 Future.get()을 각각 호출한 것을 볼 수 있습니다.아래의 이미지는 교착상태를 해결한 흐름을 나타내는 다이어그램입니다.결과적으로는 6시간 동안 실행을 했던 Github Actions도 정상적으로 완료가 되었고, 스레드 풀의 크기에 상관없이 교착상태가 더 이상 발생하지 않고 정상적으로 실행이 되는 것을 확인했습니다.아래의 공식 문서에서 클래스, 메서드 수준의 병렬화를 스레드 사용 예시와 함께 볼 수 있습니다.이번 글이 올라왔을 때는 아래의 PR이 병합되었을 것이라고 생각합니다. (현재 문서화 작업 마무리 중)대부분의 티스토리, 벨로그 글을 보면 ExtensionContext를 활용해 테스트 간 자원을 공유하는 것을 확인할 수 있습니다.하지만, 이러한 자원 공유는 범위가 병확하지 않아 특정 시점이나 테스트 세션 간 자원 관리가 복잡해질 수 있습니다.아래의 PR은 JUnit 플랫폼에서 자원 공유를 request / session 이라는 두 가지 범위로 나누어 관리할 수 있도록 하는 기능을 추가하고 있습니다.이를 통해 자원을 더 세밀하게 제어하고, 테스트 실행 간의 자원의 재사용성을 높이는 것이 목표입니다.해당 기능은 잘 모르고 사용한다면 기존의 ExtensionContext와 별 다르게 사용할 수 없다고 생각합니다.하지만 잘 알고 사용한다면 자원 공유를 매우 효율적으로 사용할 수 있습니다.각종 tech blog들에서도 분명 해당 기능이 merge가 된 후 배포가 되면 자세히 다룰 것으로 예상합니다.하지만, 문서와 코드를 보고 글을 작성하는 분들보다는 직접 만든 사람이 더 잘 알 것이라고 생각합니다. ㅎㅎ해당 글도 DEVOCEAN와 같이 접근성이 좋은 곳에 외부 기고를 하겠습니다.
junit
5/7/2025
logo
내가 JUnit5에 병렬화를 도입한 이야기 - 메서드 단위
안녕하세요, Junit-team/junit5, spring/spring-boot, apache/seata, naver/fixture-monkey 등 여러 오픈소스 프로젝트에 기여한 YongGoose입니다.처음에는 오픈소스 기여에 대한 관심을 높이려는 의도로 글을 쓰기 시작했지만, 점점 나의 소중한 자식들(?)을 소개하는 재미가 생기네요.이번 글은 아래의 글의 후속 편입니다. (미리 읽고 오시면 좋습니다)JUnit5에 병렬화를 도입한 이야기 - 클래스 단위저번 글에서는 JUnit의 Vintage 엔진에 클래스 단위의 병렬화를 도입한 것을 설명했습니다.여러 개의 테스트 클래스를 실행할 때는 해당 기능으로 인해 성능 향상을 기대할 수 있지만,만약 하나의 테스트 클래스에 있는 여러 개의 메서드를 실행할 때는 성능 향상을 기대하기 어렵습니다.그로 인해 메서드 단위의 병렬화도 메인테이너님께 제안을 드렸고, 긍정적인 답변을 받아 작업을 하게 되었습니다.메인테이너님의 코멘트에서 볼 수 있다시피 클래스 단위 병렬화에서 사용하던 스레드 풀을 활용하면 쉽게 해결이 되는 듯했습니다.그래서 위 다이어그램과 같이 Runner가 ParentRunner인 경우, 모든 childStatement(메서드)를 스레드 풀을 활용해 비동기로 실행하도록 구현했습니다.하지만, 제 기대와 달리 교착 상태가 발생하였습니다.위 이미지는 Github Actions의 워크플로우 결과 이미지인데 6시간 동안 실행을 한 뒤, 시간이 초과되어 자동으로 실패한 것을 볼 수 있습니다.이때 교착 상태는 클래스와 메서드에서 모두 병렬화를 활성화시키고, 테스트 클래스의 수보다 스레드 풀의 크기가 작을 때 발생하였습니다.클래스와 메서드 단위에서 병렬화를 모두 활성화시키면 다음과 같은 순서로 실행이 됩니다.이때 교착 상태는 테스트 클래스의 개수보다 스레드 풀의 크기가 작을 때 발생했습니다. (동일할 때도 발생했습니다)자세히 디버깅한 결과, 현재 사용 중인 스레드 풀의 특성과 연관하여 교착 상태가 발생한 원인을 확인할 수 있었습니다.실행 순서 중, 2번(각 상위 작업에 대해 실행 시작)을 할 때 하나의 스레드가 할당이 됩니다.그리고 해당 스레드는 모든 하위 작업이 완료되어 상위 작업이 완료가 되면 스레드가 반환이 됩니다.만약 스레드 풀의 크기가 3이고, 테스트 클래스의 개수가 3, 각 하위 메서드의 개수도 3이라면모든 스레드는 상위 클래스가 점유하게 되어 하위 메서드는 작업 큐에만 저장이 될 뿐 실행이 되지 않아 교착상태가 발생하는 것입니다.교착상태가 일어나는 4가지 조건과 함께 더 자세히 설명드리겠습니다.우선, 교착 상태가 일어나는 4가지 조건은 아래와 같습니다.그러면 현재의 상태에 대입해 설명하겠습니다.• None 상호 배제 : 스레드는 한 번에 하나의 작업만 사용할 수 있습니다.• None 점유 대기 : 상위 작업(클래스)은 각각 스레드를 점유한 상태에서 하위 작업(메서드)을 제출하고 완료를 기다립니다.• None 비선점 : 현재 사용 중인 스레드는 점유된 스레드를 강제로 해제하거나 다른 작업에 재할당 하지 않습니다.• None 순환 대기 : 상위 작업(클래스)은 각각 하위 작업(메서드)의 완료를 기다리고, 하위 작업(메서드)은 상위 작업(클래스)이 완료되어 스레드가 반환되기를 기다리고 있습니다.아래의 그림은 다이어그램으로 설명한 그림입니다. (조금 난잡해 보이더라도 순서대로 읽으시면 잘 이해가 될 거라고 생각합니다...)그래서 메인테이너님과 현재 상황에 대해 토론을 한 결과 ForkJoinPool을 사용하기로 결정이 되었습니다.ForkJoinPool은 작업 큐에 작업이 남아있는 경우 스레드가 블로킹되지 않고 다른 작업을 처리하는 특성을 가지고 있습니다.그래서 교착상태가 발생하는 4가지 조건 중, 순환 대기를 해결할 수 있다는 장점이 있습니다.각각의 작업이 서로의 작업의 완료를 기다리고 있는 상태가 순환 대기인데 ForkJoinPool을 활용하여 서로의 작업의 완료를 기다리지 않고 다른 작업을 처리하도록 구현하였습니다.Jupiter 엔진의 경우 이미 병렬화에서 ForkJoinPool을 사용하고 있었습니다.아래의 코드는 ForkJoinPool을 활용해 교착상태를 해결하고 메서드 단위의 병렬화를 구현한 코드입니다.work stealing을 허용하기 위해 Future.get()을 각각 호출한 것을 볼 수 있습니다.아래의 이미지는 교착상태를 해결한 흐름을 나타내는 다이어그램입니다.결과적으로는 6시간 동안 실행을 했던 Github Actions도 정상적으로 완료가 되었고, 스레드 풀의 크기에 상관없이 교착상태가 더 이상 발생하지 않고 정상적으로 실행이 되는 것을 확인했습니다.아래의 공식 문서에서 클래스, 메서드 수준의 병렬화를 스레드 사용 예시와 함께 볼 수 있습니다.이번 글이 올라왔을 때는 아래의 PR이 병합되었을 것이라고 생각합니다. (현재 문서화 작업 마무리 중)대부분의 티스토리, 벨로그 글을 보면 ExtensionContext를 활용해 테스트 간 자원을 공유하는 것을 확인할 수 있습니다.하지만, 이러한 자원 공유는 범위가 병확하지 않아 특정 시점이나 테스트 세션 간 자원 관리가 복잡해질 수 있습니다.아래의 PR은 JUnit 플랫폼에서 자원 공유를 request / session 이라는 두 가지 범위로 나누어 관리할 수 있도록 하는 기능을 추가하고 있습니다.이를 통해 자원을 더 세밀하게 제어하고, 테스트 실행 간의 자원의 재사용성을 높이는 것이 목표입니다.해당 기능은 잘 모르고 사용한다면 기존의 ExtensionContext와 별 다르게 사용할 수 없다고 생각합니다.하지만 잘 알고 사용한다면 자원 공유를 매우 효율적으로 사용할 수 있습니다.각종 tech blog들에서도 분명 해당 기능이 merge가 된 후 배포가 되면 자세히 다룰 것으로 예상합니다.하지만, 문서와 코드를 보고 글을 작성하는 분들보다는 직접 만든 사람이 더 잘 알 것이라고 생각합니다. ㅎㅎ해당 글도 DEVOCEAN와 같이 접근성이 좋은 곳에 외부 기고를 하겠습니다.
2025.05.07
junit
emoji
좋아요
emoji
별로에요
Copyright © 2025. Codenary All Rights Reserved.