테크 뉴스
테크 뉴스 더 보기
기술 블로그

효율적 시맨틱 검색을 위한 kubernetes GPU inference 시스템 구축하기
최근 인공지능(AI) 기술의 발전으로 인해 검색 분야에서도 시맨틱 검색, 즉 벡터 검색의 중요성이 부각되고 있습니다.전통적인 키워드 기반 검색과 시맨틱 검색은 각각의 강점이 있으며, 특정 상황과 요구에 따라 효과적으로 활용될 수 있습니다.키워드 기반 검색은 입력한 질의에서 주요 단어나 구문을 추출하여 문서에서 정확히 일치하거나 부분적으로 일치하는 항목을 찾아냅니다.이러한 방식은 다음과 같은 경우에 효과적입니다.• None 정확한 용어 검색: 특정한 단어나 구문을 포함하는 문서를 찾을 때 유용• None 구조화된 데이터 검색: 데이터베이스에서 정확한 필드 값을 기반으로 검색할 때 적합• None 단순하고 빠른 검색: 비교적 간단한 알고리즘으로 빠른 검색 결과를 제공시맨틱 검색은 단어와 문장의 의미를 벡터 형태로 표현하여, 질의와 문서 간의 의미적 유사성을 기반으로 검색 결과를 제공합니다. 이는 다음과 같은 상황에서 효과적입니다.• None 동의어 및 유의어 처리: 동일한 의미를 가진 다양한 표현을 인식하여 관련 결과를 제공• None 문맥 기반 검색: 단어의 문맥을 이해하여 보다 정확한 검색 결과를 제공• None 자연어 처리: 사용자의 질의를 자연어로 이해하고 처리하여, 보다 인간 친화적인 검색 경험을 제공사용자들은 원하는 정보를 찾기 위해 점점 더 복잡하고 다양한 형태의 질의를 던지고 있으며,이러한 요구에 맞춰 검색서비스는 단순한 키워드 매칭을 넘어 질의의 의도를 이해하고 의미적으로 연관된 정보를 찾아내는 방향으로 발전하고 있습니다.이러한 배경에서 검색서비스팀은 문맥 기반 검색을 강화하고자 에이닷 뉴스 검색 서비스에 시맨틱 검색을 적용했고, 검색 품질저하를 야기하는 아래 2가지 이슈를 개선하였습니다.• None 검색어와 의미적으로 관련성이 없는 뉴스 (검색어: 애플 → 이주연, 비키니로 뽐낸 글래머 몸매…섹시 애플힙)• None 검색어가 등장하긴 하지만 여러 키워드가 같이 등장해 관련성이 떨어지는 뉴스 (검색어: 애플 → 삼성전자, 미래 가치 브랜드서 애플 제쳤다...퓨처브랜드 1위)이를 실현하기 위해서는 실시간 수준의 시맨틱 검색이 가능해야 하며, 대규모 데이터를 빠르게 처리할 수 있는 GPU와 같은 고성능 인프라 구축과 효율적인 활용이 필수적입니다.최근 GPU 인프라 기술의 발전으로 이러한 복잡한 연산을 실시간으로 처리하는 것이 가능해졌습니다.특히, NVIDIA의 triton inference server는 다양한 AI 모델의 추론을 효율적으로 수행할 수 있도록 설계되어 GPU의 성능을 최대한 활용하여 실시간으로 AI 모델을 서빙하는 데 최적화되어 있으며,kubernetes를 활용하여 컨테이너 기반의 애플리케이션 배포, 스케일링 및 관리를 자동화하여, 확장 가능하고 안정적으로 운영할 수 있습니다.이러한 배경에서 검색서비스팀은 시맨틱 검색, 나아가서 LLM 기반의 질의 분석 등의 활용을 위해 GPU 기반 추론 서버를 kubernetes 클러스터에 구축하였습니다.이 글에서는 NVIDIA triton inference server와
SK텔레콤
·
오늘

신속한 배포를 위한 Shift-Left Testing 방법론
소프트웨어 개발이 점점 빠르고 복잡해짐에 따라 품질을 보장하는 방법도 변화가 필요합니다.전통적인 품질보증(QA, Quality Assurance) 활동이 개발 이후 결함을 발견하고 수정하는 것에 중점을 두었다면,Quality Engineering(QE)은 결함 예방과 품질 향상을 개발의 초기 단계부터 내재화하는 접근법입니다.기존의 전통적인 개발 프로세스(SDLC)는 보통 다음과 같은 선형적이고 단계적인 접근 방식을 따릅니다.• None 각 단계가 독립적으로 진행되며 순차적으로 이어짐• None 테스트가 개발 완료 후에 이루어짐• None 결함 발견 시 수정 비용과 시간이 많이 소모됨• None 후기 단계에서 문제 발견 시 배포 일정이 지연될 가능성이 큼QE의 목적은 결함을 SDLC 프로세스 앞 단에서 발견하여 신속하게 문제를 발견하고 수정하여 빠른 소프트웨어 배포 주기를 갖는 것입니다.이 과정을 통해 시장 대응력을 확보하고 소프트웨어 안정성과 신뢰성을 강화하여 고객 만족도를 높이는 것이 목적입니다.QE 접근법은 다음과 같은 특징을 가지고 있습니다.• None 결함 예방 중심: 문제 발생 후 수정보다는 사전에 결함을 예방하는 것이 핵심입니다.• None 조기 테스트 수행: 요구사항 정의, 설계 단계에서부터 테스트 활동을 수행합니다.• None 자동화와 효율성 강조: 지속적 통합(CI) 및 지속적 배포(CD)를 통한 빠른 피드백 루프를 구축합니다.Shift-Left Testing은 소프트웨어 개발 주기(SDLC)의 초반 단계부터 적극적으로 테스트를 수행하여 잠재적인 결함을 조기에 발견하고 해결하는 접근 방법입니다.간단히 말해, 테스트 시점을 "왼쪽으로" 이동시키는 것이 핵심입니다. 이를 통해 품질 비용을 최소화하고, 전 과정에서 빠르고 지속적인 피드백을 제공합니다.Agile Testing (애자일 테스팅) 과 비교해 볼 수 있습니다. 애자일 테스팅은 스프린트 주기 내의 반복적이고 유연한 테스트를 강조하며, 주로 스프린트 끝에서 품질 검증이 이루어집니다.따라서 목표는 각 스프린트 종료 시점에 완성도 높은 제품을 제공하는 데 있습니다.• None• None 요구사항 스펙 및 사용자 스토리 명확화하고 개발자, QA 엔지니어, 운영팀 간 긴밀한 협력과 의사소통을 통해 품질에 대한 책임을 공동으로 가집니다.• None 기획자와 개발자간의 상세 리뷰를 수행할때 QA 리뷰를 함께 진행하여 초기 요구사항 리뷰를 함께 수행합니다.• None Sanity Test, Smoke Test 등을 수행함으로써 역할에 따라 품질 보증을 수행합니다.• None 정기적인 리뷰 및 회고를 통해 지속적인 프로세스 개선을 유도합니다.• None• None 클래스나 함수 구조 간단히 유지하고 빌드가 됨과 동시에 자동화된 단위테스트와 통합 테스트 실행합니다.• None 단위 테스트, 통합 테스트 및 API 테스트를 자동화하여 빌드 시마다 즉각적으로 결함을 탐지합니다.• None 반복적이고 시간이 많이 소모되는 테스트를 자동화하여 효율성을 높이고 빠르게 피드백을 제공합니다.• No
SK텔레콤
·
오늘

AI 툴 개발은 처음이라, 당근 비개발자 구성원들의 AI 도전기
AI 툴 개발은 처음이라, 당근 비개발자 구성원들의 AI 도전기 — 당근 AI Show & Tell #1해당 이미지는 OpenAI의 이미지 생성 모델인 DALL·E를 활용하여 GPT-4o에서 생성되었습니다.최근 IT 업계는 생성형 AI의 등장으로 또 한 번의 큰 전환점을 맞이했어요. 사용자 경험이 AI 중심으로 재편되면서, 기존 서비스의 PMF(Product Market Fit)가 빠르게 무너지는 사례가 많아졌죠. 하루아침에 기존 방식이 낡은 것으로 여겨지는 시대가 열린 거예요. 당근도 이런 흐름 속에서 멈춰 있지 않고, AI를 활용한 다양한 실험을 빠르게 시도하고 있어요.이 과정에서 중요한 건 완벽한 정답을 찾는 게 아니라, 실패하더라도 직접 실험하고 실행해보는 경험 그 자체예요. 당근은 매주 화요일마다 ‘AI Show & Tell’을 통해 각 팀의 프로젝트와 시행착오를 공유하고 있어요. 단순한 결과가 아닌, 실패 속에서 얻은 인사이트까지 나누는 자리죠. 업무나 서비스에 AI를 적용한 사례부터 개발 중인 기능의 어려움, 새로운 아이디어까지 다양하게 공유하면서, 모두가 함께 새로운 가능성을 발견하고 있어요.앞으로 당근의 AI Show & Tell에서 공유되는 실험들을 생생하게 나누려고 해요. 특히 이번 글에서는 직군에 관계없이 누구나 AI에 도전할 수 있다는 가능성을 보여주는 프로젝트 세 가지를 소개해 드릴게요. 엔지니어뿐 아니라 프로덕트 디자이너, CEO Staff, 운영 매니저까지 얼마나 다양한 구성원들이 AI 실험에 도전하고, 자신의 업무에서 변화를 만들어가고 있는지 확인해보세요. 🚀개발은 몰라도, AI 실험은 누구나Project 1. 디자이너가 직접 만든 피그마 플러그인, ‘Ratiosnap’로컬비즈니스의 Product Designer Hazel은 Cursor를 활용해, 업무에 필요한 피그마 플러그인을 직접 개발했어요. 시작은 아주 사소한 불편함이었죠. 피그마에서 UI 여백을 2:3 비율로 배치하고 싶었는데, px 단위로 매번 직접 계산해서 넣어야 했거든요. 처음엔 ChatGPT에게 비율 계산을 요청하고 그 값을 복사해 사용하는 식으로 해결했지만, 이마저도 반복되다 보니 꽤 번거롭게 느껴졌어요. 결국 이런 수고로움을 줄이기 위해, 디자인 요소의 위치를 자동으로 조정해주는 플러그인을 직접 만들어보기로 했어요.개발 지식이 거의 없는 Hazel은 단 30분 만에 피그마 플러그인 ‘Ratiosnap’을 완성했어요. 더 놀라운 건 “이런 기능을 만들어줘”라고 구체적인 지시를 내리지 않았다는 점이에요. 평소에 겪던 비효율적인 작업 방식을 설명하고 아이디어를 요청했을 뿐인데, Cursor는 문제를 분석하고 기능 요구사항까지 마치 PRD처럼 정리해주었어요. Hazel은 그 흐름을 따라가며 필요한 부분은 피드백하고 디자인과 기능을 조율했죠. UI 구성부터 코드 작성까지 대부분의 과정을 AI가 주도했고, Hazel은 디자이너로서의 관점과 감각을 더해가며 제품을 완성해 나갔어요.이 경험은 Hazel에게 단순한 플러그인 제작 이상의 의미였어요. 디자이
당근
·
하루 전

Apache Airflow를 시작하는 가장 쉬운 방법, Astro CLI
Apache Airflow에 대해 자주 이야기가 나오는 것이 있습니다.• None 로컬 환경에서 세팅하기 어렵다.이런 이야기의 배경에는 설치부터 공식 문서에서 방대한 양의 세팅 관련 문서를 마주했던 경험과,실행 및 테스트를 위해 추가적인 도구(Airflow Breeze) 혹은 명령어를 추가로 학습해야 했고 그마저도 사용하기 쉬운 것과는 거리가 멀었기 때문입니다.이러한 이유로 많은 사람들이 "Airflow를 어렵다"고 느낍니다.그런데 만약 Apache Airflow를 쉽게 설치하고, 단 몇 개의 명렁어만으로도 실행과 테스트를 할 수 있다면 어떨까요?Apache Airflow 생태계에 많은 기여를 해온 Astronomer은 이 문제를 해결하기 위해 Apache Airflow를 설치하는 가장 쉬운 방법, Astro CLI라는 것을 개발했습니다.그리고 이를 오픈소스로 공개하여 누구나 손쉽게 Airflow를 설치하고 사용할 수 있게 되었습니다.이 글을 통해서 Astro CLI를 어떻게 사용할 수 있는지 알아보도록 하겠습니다.설치는 공식 홈페이지를 참고하여 설치할 수 있습니다.설치가 완료되었는지 아래의 명령어를 통해 정상적으로 설치되었는지 확인해봅시다.과연 얼마나 쉽게 실행이 가능하길레 이렇게 호들갑인가 싶을 것입니다.AstroCLI를 사용하면 단 3개의 직관적인 명령어만으로 프로젝트를 세팅하고 실행하고 중지할 수 있습니다.• None 으로 Airflow UI 가 나오면 Username과 Password에 과 을 쳐서 들어갑니다.한 번이라도 Airflow를 직접 세팅하느라 어려움을 겪으셨던 분이나,처음 공부하실 때 공식문서의 “Installation of Airflow”를 보고 벽을 느끼셨던 분들은 이것이 얼마나 감동적인 경험인지 공감하실 것입니다.그럼 조금 더 자세히 알아보도록 하겠습니다.프로젝트 폴더에서 astro dev init을 실행하면 프로젝트의 기본 디렉토리 구조가 생성됩니다.디랙토리 구조는 다음과 같습니다:Airflow의 connection, variable, pools를 설정하는 방법에는 두 가지가 있습니다.이 과정은 Astro CLI를 사용하지 않더라도 동일하기 때문에 이미 익숙할 수 있으므로 간단히 넘어가겠습니다.Airflow UI에서 직접 설정할 수 있습니다. UI에서 "Admin" → "Connections/Variables/Pools"로 이동해서 설정하시면 됩니다.파일을 통해 아래와 같이 connections, variables, pools을 설정할 수 있습니다.Airflow를 사용할 때, 일반적으로 파일을 사용합니다.하지만 Astro CLI를 사용한 프로젝트는 파일에 설정된 값을 기반으로 를 생성하기 떄문에 파일을 사용하여 환경변수를 설정합니다.따라서 별도로 를 수정하거나 설정할 필요가 없습니다.환경변수를 확인하려면 아래 명령어로 확인할 수 있습니다:이 명령어로 생성된 파일의 내용을 확인할 수 있습니다.Airflow의 특정 버전으로 프로젝트 생성하기아무 옵션없이 을 실행했을 때는 설치된 Astro CLI에 기본 설정된 as
SK텔레콤
·
2일 전

Playwright로 효율적인 FrontEnd 개발 시나리오 테스트하기
안녕하세요, 이번 글에서는 지난번 글에서 소개해드렸던 통합 테스트와 playwright를 직접 적용해 보도록 하겠습니다.들어가며어떠한 기술을 소개만 하는게 아니라 직접 적용하는 과정 까지 보여드리면 더욱 좋을 것 같아 작성하게 되었습니다. 현재 직접적인 프로젝트에 도입은 못하고 있습니다. 개발 기한이 촉박하고, 이미 코드가 많이 생성되어 버린 상황이어서 도입하기가 까다로울 수 있습니다. 하지만 꾸준히 필요성을 이야기하고 있고, 사용 예를 작성하여 가이드를 보여드리려 합니다. 아래의 내용에서는 어떠한 상황에서 테스트를 하고, 이점이 있을지에 대해 이야기 해보겠습니다.시나리오 검증테스트를 도입하려 하는데 가장 큰 이유는 시나리오 검증입니다. MSW를 사용해서도 가능하지만 만약 api의 응답이 시나리오 흐름에 따라 바뀌어야 한다면 MSW의 응답을 직접 바꾸어 주어야 하기에 동작의 흐름을 한번에 보지 못합니다. 하지만 Playwright를 이용하면 가능한데요, 저는 아래와 같은 시나리오를 생각하고 테스트 코드를 작성, 검증을 진행해 보았습니다.먼저 window alert, prompt에 대한 동작을 정의하였습니다. 앱의 웹뷰를 개발하며 앱 인터페이스를 사용해야 하는 경우가 많은데, 이를 대응하기 위하여 wrapper를 사용하였습니다. window alert, prompt를 이용하여 임의의 값을 전달하면 해당 값으로 동작하도록 구성되어 있습니다. 테스트 코드 내에서는 dialog이벤트가 발생하면 이벤트 핸들러를 이용하여 alert인지, prompt인지 구분하고 prompt일 때는 세부적으로 어떠한 prompt인지 구별한 후 테스트에 사용할 임의의 값을 전달합니다. 이렇게 하면 테스트를 할 때 직접 값을 입력해주어야 하는 번거로움이 사라집니다.// dialog event 처리test('충전 진행 중 중단 test', async ({page}) => { let deleteAResponse: boolean = false; // API 응답 값을 저장할 변수 page.on('dialog', async (dialog) => { if (dialog.type() === 'alert') { /** * Alert 이면 확인을 누름 */ await dialog.accept(); } }); page.on('dialog', async (dialog) => { if (dialog.type() === 'prompt') { const promptMessage = dialog.message(); /** * 위치 조회에 필요한 longitude, latitude 전달 */ if (promptMessage.includes('latitude')) { await dialog.accept(LATITUDE); } else if (promptMessage.includes('longitude')) { await dialog.accept(LONGITUDE); } else if (promptMessage.includes('Confirm')) { await dialog.accept('0'); } } });그 다음 필요한 api를 mocking합니다. 어떠한 값으로 실행될 지 미리 정의하여 route를 이용하여 status, body 등을 정의 합니다./** * 충전 진행 중 정보 api mocking */ await page.route('/api/path', (route) => { route.fulfill({ status: 200, body: JSON.stringify({}); });...이제 필요한 준비를 하였으니 시나리오 검증을 시작합니다. 먼저 해당 페이지로 이동하고, 그 페이지에서 어떠한 흐름으로 동작을 테스트 할지 정의 하여 테스트를 합니다./** * 충전 페이지로 이동 */ await page.goto(TEST_URL); /** * 충전 중단 클릭 */ await page.getByText('Stop Charging').click(); const response = await page.waitForResponse( (response) => response.url().includes('/api/path') && response.status() === 200 && response.request().method() === 'DELETE' ); /** * 충전 진행 중 컴포넌트가 사라졌는지 확인 */ await page.waitForSelector('#inProgressItem', {state: 'detached', timeout: 2000}); // 2초 동안 컴포넌트가 사라질 때까지 기다림, 2초 이후에도 남아있으면 테스트 통과 못함 await expect(page.locator('#inProgressItem')).toBeHidden(); });이렇게 진행하면 다양한 브라우저에서 병렬로 테스트 진행이 가능하고 테스트 결과를 확인할 수 있습니다.에러 상황 검증두번째 이유는 에러 상황에 대한 검증이었습니다. 특정 에러에 대해 사용자에게 노출되어야 하는 팝업의 내용이 달라지거나, 내부 로직이 달라지는 경우에도 제대로 구현이 되었는지 검증이 필요합니다. 이러한 상황에서 의도적인 에러 상황을 만들고, 구현이 제대로 되었는지 검증할 수 있습니다.// 1. 404 에러 처리 test('404에러 발생 시 사용자 경고 메시지 확인', async ({page}) => { await page.route('**/api/not-found', (route) => { route.fulfill({ status: 404, body: JSON.stringify({error: 'Not Found'}), }); }); await page.goto(TEST_URL); await page.click('text=Trigger 404 Error); // 버튼 클릭 등 404 에러 유발 action const alertMessage = await page.locator('.error-message').textContent(); expect(alertMessage).toContain('요청한 페이지를 찾을 수 없습니다.'); }); // 2. 500 서버 에러
현대자동차그룹
·
2일 전

캐시를 적용하기 까지의 험난한 길 (TPS 1만 안정적으로 서비스하기)
토스 커뮤니티, 그리고 토스뱅크에서는 하루에 수 백번의 라이브 배포가 일어나고 있으며 다양한 개선점과 신규 제품들이 빠르게 출시되고 있어요. 이렇게 많은 배포를 기반으로 토스뱅크가 성장하면서 토스뱅크를 이용하는 사용자도 많아졌는데요. 이로 인해서 TPS가 평균 1만, 최대 2만까지 늘어난 약관(terms) 서버에 안정적인 서비스 제공을 위해 캐시를 적용한 이야기를 들려드리려고 해요.약관 서버는 사용자가 동의 또는 철회한 약관 및 동의서 동의 여부를 기록하고 조회할 수 있는 서비스예요. 사용자가 동의 그리고 철회하는 경우는 그렇게 많지 않지만, 동의 여부에 따라서 개인 정보를 제3자에게 제공해도 되는지, 토스뱅크가 사용해도 되는지 등 다양한 비지니스에서 약관 및 동의서 동의 여부를 확인해요.어느 날, 토스뱅크에서 새로운 서비스를 배포하면서 TPS가 급증했고, 이로 인해 DB 조회량이 급증하여 DB 부하가 심각해졌었어요. 이 트래픽이 유지될 경우 다른 서비스에도 문제가 생길 수 있다고 판단했고, 급히 롤백을 진행하며 DB 부하를 줄일 방안을 고민하게 되었어요. 그 결과, 많은 분들이 알고 계신 ‘캐시’를 적용하기로 했지만, 막상 시도해 보니 생각보다 간단치 않았어요.캐시 적용은 보다 신중하게이 글을 읽으면서, “어? 그럼 Replication된 Database를 두고 부하를 분산하면 되는거 아니야?” 라고 생각할 수 있어요. 약관은 토스뱅크 고객의 개인정보와 밀접한 연관성이 있어요. 약관 동의 여부는 사용자의 정보를 특정 목적으로 이용해도 되는지, 제3자에게 공유가 되도 되는지 결정하는 기준이기 때문이에요.그래서 약관 동의 여부는 값이 DB에 Commit 되는 순간, 바로 다음 요청에 DB에 저장된 값이 정확하게 응답되어야해요. 이를 Strong Consistency라고 부르며, 데이터의 무결성을 보장하기 위해 필수적이에요. 만약, 잘못된 응답을 한 번이라도 발생하면, 고객이 약관을 철회한 이후에도 개인정보가 공유되는 등의 보안 문제가 발생할 수 있어요. 따라서 데이터 신뢰성과 정확성을 보장하기 위해 Replication Database는 사용하지 않기로 했어요. Replication 구조에서는 복제 지연(Replication Delay)이 발생할 가능성이 있기 때문이에요. 대신, Strong Consistency를 유지하면서도 빠르게 조회가 가능한 Redis Cache를 활용해 고객의 약관 동의 상태를 안전하게 관리하기로 결정했어요.이러한 방식으로 캐시를 적용했어요!약관 서버는 대부분 조회성으로 캐시를 접근하므로, DB의 정보가 자주 변경되지 않고, 대부분의 케이스는 Cache Hit를 하기 때문에, Look-aside 전략을 사용했어요. Look-aside 전략은 캐시에 원하는 데이터가 있는지 먼저 확인하고, 데이터가 없다면 DB에 접근한 후에 캐시에 저장하고 응답하는 방식이예요. 만약 DB 정보가 자주 변경된다면 다른 방식을 고민해야해요.캐시 만료처리는 Spring의 와 를 사용해서, DB에 Commit된 이후에 캐시가 만료되도록 했어
비바리퍼블리카
·
2일 전
기술 블로그 더 보기
테크 뉴스
테크 뉴스 더 보기
코드너리에서 이용할 수 있는
새로운 기능
새로운 기능
지금 확인해 보세요!

이달의 컨퍼런스
컨퍼런스 일정 더 보기