logo
emoji
검색하기
어제 가장 많이 검색된 기술
emoji
가장 많이 읽은 글
logo
프롬프트 엔지니어링, AI를 똑똑하게 활용하는 방법
안녕하세요, 데보션 영 3기 TechWave팀의 김유빈입니다🌊 오늘은 프롬프트 엔지니어링을 주제로 글을 작성해보고자 합니다.Gemini, ChatGPT, Midjourney 등 다양한 생성형 AI가 등장하는 요즘, 생성형 AI는 정말 다양한 분야에서 활용되고 있습니다.하지만, 잘못된 정보를 사실처럼 답변하는 Hallusination(할루시네이션)과 같은 한계점 역시 드러나고 있어,AI모델로부터 더 정확한 답변을 이끌며 동시에 오류를 줄이는 Prompt Engineering (프로프트 엔지니어링)의 중요도가 점점 높아지는 추세입니다.이렇듯 프롬프트 엔지니어링의 수요가 점차 높아지고 있으며, 최근에는 뤼튼과 같은 국내 스타트업에서도 이러한 기법을 유치하기 위해 많은 노력을 기울이고 있습니다.프롬프트를 거래하거나 무료로 공유하는 마켓플레이스 역시 증가하고 있으며 ChatGPT에서도 다양한 프롬프트 모델들을 확인하실 수 있습니다.프롬프트 엔지니어링은 언어모델(LM)을 효율적으로 사용할 수 있도록 입력값들을 조합하여 프롬프트를 개발하고 최적하는 작업입니다.이 글에서는 프롬프트 엔지니어링 가이드를 통해 보다 똑똑하게 AI를 활용하는 방법을 제시해보겠습니다.* 하단의 내용은 https://www.promptingguide.ai 를 참조하여 작성하였습니다.프롬프트는 AI 모델의 응답을 생성하기 위한 입력값입니다.프롬프트에는 다음과 같은 4가지 구성 요소들이 있습니다. 모든 요소들이 반드시 포함되어야 하는 것은 아닙니다.먼저, 프롬프트 엔지니어링은 AI 중 NLP(자연어처리) 의 개념으로, 프롬프트 입력값들의 조합을 찾아 output의 품질을 높이는 작업입니다.그러다면, 이 프롬프트 엔지니어링이 중요한 이유는 무엇일까요?이는 AI의 성능이 프롬프트에 크게 영향을 받기 때문입니다. 프롬프트를 똑똑하게 사용하면, AI를 능력을 최대로 사용하여 고질적인 문제점을 줄일 수 있기 때문에,프롬프트 엔지니어링은 매우 중요한 작업이 되었습니다.이제 본격적으로 프롬프트를 잘, 그리고 똑똑하게 쓰는 방법을 정리해보겠습니다.아래 내용의 다수는https://www.promptingguide.ai 에서 발췌하였음을 다시 한번 밝힙니다.먼저, API를 똑똑하게 사용하는 방법을 다루어보겠습니다. 아래는 AI 모델의 파라미터에 대한 설명입니다.: 답변의 창의성, 무작위성에 관여합니다.사실을 기반으로 하는 질의응답과 같은 작업에는 낮은 값(ex. 0.01)을 사용하여 보다 사실적이고 보다 일관된 응답을 얻을 수 있습니다.시를 생성하는 등 창의적인 작업의 경우에는 값을 높이는 것(ex. 1)이 좋습니다.: temperature와 함께 반응의 변동성을 관리하는 데 사용됩니다.이렇게 이야기하면 위 temperature와 매우 비슷해보이는데요, temparature가 확률 분포를 조정한다면, top_p는 그 확률분포 내에서 선택할 단어의 범위를 결정합니다.top_p가 낮을수록 응답의 정확도는 높아지지만 응답의 다양성은 낮아집니다. top_p가 높을수록 다양한 출력을 유도합니다.가이드에서는 둘 중 하나만 변경하는 것을 권장합니다.: max length를 조정하여 모델이 생성하는 토큰의 수를 관리할 수 있습니다.지나치게 길거나 주제에서 벗어난 답변을 방지하는 데 도움이 됩니다. 또한, 비용을 효율적으로 관리하는데 도움이 될 수 있습니다.: 모델의 토큰 생성을 중지하는 문자열입니다. stop sequences를 지정하는 것은 모델의 응답 길이 및 구조를 제어하는데 도움이 될 수 있습니다.예를 들어, stop sequence로 "11"을 추가하여 항목이 10개를 초과하지 않는 리스트를 생성하도록 모델에 지시할 수 있습니다.: 이 설정은 모델이 동일한 단어나 구를 반복하지 못하도록 합니다.frequency penalty가 높을수록 단어가 다시 등장할 가능성이 줄어듭니다. 자주 등장하는 토큰에 대하여 더 많은 페널티를 부여하여 모델의 응답에서 단어의 반복을 방지합니다.: presence penalty는 반복되는 토큰에 패널티를 적용하지만, frequency penalty와 달리 모든 토큰에 동일한 페널티가 적용됩니다.즉, 토큰이 2회 등장하는 토큰과 10회 등장하는 토큰이 동일한 페널티를 받습니다.이를 통해 다양한 답변이 나오도록 유도할 수 있으며, 더 다양하고 창의적인 텍스트를 원하면 증가, 집중된 콘텐츠를 원하면 낮출 수 있습니다.temperature 및 top_p와 유사하게, 가이드에서는 frequency penalty와 presence penalty 중 하나만 변경하거나 둘 다 변경하지 않는 것을 추천하고 있습니다.* 위 내용은 사용하는 LLM 버전, 그리고 모델에 따라 결과가 상이할 수 있습니다.다음으로 프롬프트를 설계할 때 주의할 사항들입니다. 이 기초 규칙들을 통해 프롬프트를 더 똑똑하게 작성할 수 있습니다.AI에게 질문할 떄 명령어를 사용하여 지시함으로서 더 효과적인 프롬프트를 설계할 수 있습니다.또한, 수행시키려는 내용과 관련된 문맥이 구체적이고 적절할수록 더 좋은 결과를 얻을 수 있습니다.단순 지시만 하는 것이 아닌, 사용자가 정확하게 어떤 답을 기대하고 지시를 했는지 서술하는 것이 좋은 프롬프트입니다.프롬프트는 구체적이고 직접적일수록 좋은 결과를 얻을 수 있습니다. 사람과 대화할 때도 정확하게 질문할수록 더 효과적인 답변을 얻을 수 있는데요, 이와 같은 맥락으로 질문해야 합니다.위 나쁜 예시에서는 지시가 불명확한데요, 좋은 예시 처럼 구체적이고 간결할수록 정확한 결과를 얻을 수 있습니다.3. "해야 하는 것" 에 집중하기'하지 말아야 할 것'보다는 '해야 하는 것'에 초점을 두는 것이 좋습니다. 이 방법을 통해 AI는 세부 사항에 집중할 수 있습니다.위 나쁜 예시에서는 다음과 같은 답변을 얻었는데요,보시는 것처럼, 정확하지 않은 실패한 답변을 얻게 되었습니다.반면 위와 같이 개선해보니 훨씬 정확한 답변을 얻을 수 있었습니다.이렇게 기본적인 프롬프트 입력 예시들을 알아보았는데요,이러한 프롬프트로 할 수 있는 기본적인 태스크들은 다음과 같습니다: 문장 요약, 정보 추출, 질의응답, 텍스트 분류, 대화, 코드 생성,
5/2/2024
logo
프롬프트 엔지니어링, AI를 똑똑하게 활용하는 방법
안녕하세요, 데보션 영 3기 TechWave팀의 김유빈입니다🌊 오늘은 프롬프트 엔지니어링을 주제로 글을 작성해보고자 합니다.Gemini, ChatGPT, Midjourney 등 다양한 생성형 AI가 등장하는 요즘, 생성형 AI는 정말 다양한 분야에서 활용되고 있습니다.하지만, 잘못된 정보를 사실처럼 답변하는 Hallusination(할루시네이션)과 같은 한계점 역시 드러나고 있어,AI모델로부터 더 정확한 답변을 이끌며 동시에 오류를 줄이는 Prompt Engineering (프로프트 엔지니어링)의 중요도가 점점 높아지는 추세입니다.이렇듯 프롬프트 엔지니어링의 수요가 점차 높아지고 있으며, 최근에는 뤼튼과 같은 국내 스타트업에서도 이러한 기법을 유치하기 위해 많은 노력을 기울이고 있습니다.프롬프트를 거래하거나 무료로 공유하는 마켓플레이스 역시 증가하고 있으며 ChatGPT에서도 다양한 프롬프트 모델들을 확인하실 수 있습니다.프롬프트 엔지니어링은 언어모델(LM)을 효율적으로 사용할 수 있도록 입력값들을 조합하여 프롬프트를 개발하고 최적하는 작업입니다.이 글에서는 프롬프트 엔지니어링 가이드를 통해 보다 똑똑하게 AI를 활용하는 방법을 제시해보겠습니다.* 하단의 내용은 https://www.promptingguide.ai 를 참조하여 작성하였습니다.프롬프트는 AI 모델의 응답을 생성하기 위한 입력값입니다.프롬프트에는 다음과 같은 4가지 구성 요소들이 있습니다. 모든 요소들이 반드시 포함되어야 하는 것은 아닙니다.먼저, 프롬프트 엔지니어링은 AI 중 NLP(자연어처리) 의 개념으로, 프롬프트 입력값들의 조합을 찾아 output의 품질을 높이는 작업입니다.그러다면, 이 프롬프트 엔지니어링이 중요한 이유는 무엇일까요?이는 AI의 성능이 프롬프트에 크게 영향을 받기 때문입니다. 프롬프트를 똑똑하게 사용하면, AI를 능력을 최대로 사용하여 고질적인 문제점을 줄일 수 있기 때문에,프롬프트 엔지니어링은 매우 중요한 작업이 되었습니다.이제 본격적으로 프롬프트를 잘, 그리고 똑똑하게 쓰는 방법을 정리해보겠습니다.아래 내용의 다수는https://www.promptingguide.ai 에서 발췌하였음을 다시 한번 밝힙니다.먼저, API를 똑똑하게 사용하는 방법을 다루어보겠습니다. 아래는 AI 모델의 파라미터에 대한 설명입니다.: 답변의 창의성, 무작위성에 관여합니다.사실을 기반으로 하는 질의응답과 같은 작업에는 낮은 값(ex. 0.01)을 사용하여 보다 사실적이고 보다 일관된 응답을 얻을 수 있습니다.시를 생성하는 등 창의적인 작업의 경우에는 값을 높이는 것(ex. 1)이 좋습니다.: temperature와 함께 반응의 변동성을 관리하는 데 사용됩니다.이렇게 이야기하면 위 temperature와 매우 비슷해보이는데요, temparature가 확률 분포를 조정한다면, top_p는 그 확률분포 내에서 선택할 단어의 범위를 결정합니다.top_p가 낮을수록 응답의 정확도는 높아지지만 응답의 다양성은 낮아집니다. top_p가 높을수록 다양한 출력을 유도합니다.가이드에서는 둘 중 하나만 변경하는 것을 권장합니다.: max length를 조정하여 모델이 생성하는 토큰의 수를 관리할 수 있습니다.지나치게 길거나 주제에서 벗어난 답변을 방지하는 데 도움이 됩니다. 또한, 비용을 효율적으로 관리하는데 도움이 될 수 있습니다.: 모델의 토큰 생성을 중지하는 문자열입니다. stop sequences를 지정하는 것은 모델의 응답 길이 및 구조를 제어하는데 도움이 될 수 있습니다.예를 들어, stop sequence로 "11"을 추가하여 항목이 10개를 초과하지 않는 리스트를 생성하도록 모델에 지시할 수 있습니다.: 이 설정은 모델이 동일한 단어나 구를 반복하지 못하도록 합니다.frequency penalty가 높을수록 단어가 다시 등장할 가능성이 줄어듭니다. 자주 등장하는 토큰에 대하여 더 많은 페널티를 부여하여 모델의 응답에서 단어의 반복을 방지합니다.: presence penalty는 반복되는 토큰에 패널티를 적용하지만, frequency penalty와 달리 모든 토큰에 동일한 페널티가 적용됩니다.즉, 토큰이 2회 등장하는 토큰과 10회 등장하는 토큰이 동일한 페널티를 받습니다.이를 통해 다양한 답변이 나오도록 유도할 수 있으며, 더 다양하고 창의적인 텍스트를 원하면 증가, 집중된 콘텐츠를 원하면 낮출 수 있습니다.temperature 및 top_p와 유사하게, 가이드에서는 frequency penalty와 presence penalty 중 하나만 변경하거나 둘 다 변경하지 않는 것을 추천하고 있습니다.* 위 내용은 사용하는 LLM 버전, 그리고 모델에 따라 결과가 상이할 수 있습니다.다음으로 프롬프트를 설계할 때 주의할 사항들입니다. 이 기초 규칙들을 통해 프롬프트를 더 똑똑하게 작성할 수 있습니다.AI에게 질문할 떄 명령어를 사용하여 지시함으로서 더 효과적인 프롬프트를 설계할 수 있습니다.또한, 수행시키려는 내용과 관련된 문맥이 구체적이고 적절할수록 더 좋은 결과를 얻을 수 있습니다.단순 지시만 하는 것이 아닌, 사용자가 정확하게 어떤 답을 기대하고 지시를 했는지 서술하는 것이 좋은 프롬프트입니다.프롬프트는 구체적이고 직접적일수록 좋은 결과를 얻을 수 있습니다. 사람과 대화할 때도 정확하게 질문할수록 더 효과적인 답변을 얻을 수 있는데요, 이와 같은 맥락으로 질문해야 합니다.위 나쁜 예시에서는 지시가 불명확한데요, 좋은 예시 처럼 구체적이고 간결할수록 정확한 결과를 얻을 수 있습니다.3. "해야 하는 것" 에 집중하기'하지 말아야 할 것'보다는 '해야 하는 것'에 초점을 두는 것이 좋습니다. 이 방법을 통해 AI는 세부 사항에 집중할 수 있습니다.위 나쁜 예시에서는 다음과 같은 답변을 얻었는데요,보시는 것처럼, 정확하지 않은 실패한 답변을 얻게 되었습니다.반면 위와 같이 개선해보니 훨씬 정확한 답변을 얻을 수 있었습니다.이렇게 기본적인 프롬프트 입력 예시들을 알아보았는데요,이러한 프롬프트로 할 수 있는 기본적인 태스크들은 다음과 같습니다: 문장 요약, 정보 추출, 질의응답, 텍스트 분류, 대화, 코드 생성,
2024.05.02
emoji
좋아요
emoji
별로에요
logo
[Kotlin] DataClass와 Sealed Class 알아보기
• None 프로그램을 작성하다 보면, 오직 데이터를 실어 나르기 위한 객체를 만들어할 때가 있다.• None 이럴때 data class 를 사용하여 클래스를 생성하고, 데이터를 담을 수 있다.• None 위와 같이 data class 로 선언한다.• None Person은 데이터 클래스의 이름이다.• None data class는 name과 age 라는 속성을 가진다.• None 중요한 포인트는 data class는 copy(), equals(), hashCode(), toString() 에 대한 메소드를 자동으로 미리 구현되어 있다.• None 개발자가 직접 메소드를 작성할 필요가 없다.• None 기본 생성자는 무조건 1개 이상의 파라미터가 필요하다.• None 기본 생성자의 파라미터는 반드시 val(읽기 전용)이나 var(읽기-쓰기 가능) 를 가져야한다.• None 클래스는 open이 될수 없다. 즉, 상속이 불가능하다.• None abstract 도 될수 없다. 즉, 객체의 상속을 의도하지 않기 때문에 추상 클래스도 될 수 없다.• None inner이나 sealed 도 될수 없다.• None data class를 이제 만들어 보자.• None 08.01.data_class_sample.kt 파일을 다음과 같이 작성하자.• None 결과는 다음과 같다.• None 자동으로 toString 메소드가 구현되어 있으므로 println로 객체자체를 출력할때 Person(name=UncleBae, age=40) 이 출력되는 것을 확인할 수 있다.• None data class는 copy() 함수가 이미 구현되어 있다.• None 이를 이용하여 원래 data class로 부터 새로운 data class를 복사하고, 원하는 값을 변경할 수 있다.• None 08.02.data_class_sample.kt 파일을 다음과 같이 작성하자.• None 결과는 다음과 같다.• None 즉, copy 메소드를 이용하여 원래 값에서 이름만 바꾼 새로운 값을 생성하였다.• None hashCode() 는 객체 값을 이용하여 해시 코드를 생성한다. 즉, 값의 유니크성을 확인할 수 있도록 해주는 함수이다.• None equals() 는 객체 내부의 값이 동일한지 검사한다.• None 다음과 같이 08.03.data_class_sample.kt 파일을 다음과 같이 작성한다.• None 결과는 다음과 같다.• None 즉, person01에서 copy를 통해서객체를 그대로 복사했다. 이때 hashCode는 둘다 동일한 값을 가진다.• None 다만, 복사를 하고 해당 값을 변경하면 다른 값이 불러지게 된다.• None 데이터 객체로 부터 값을 조회할때 해당 데이터 클래스 값을 분해하여 반환 받을 수 있다.• None 이를 Destruction이라고 부른다.• None 08.04.data_class_sample.kt 파일을 다음과 같이 작성하자.• None 결과는 다음과 같다.componentN 형식으로 값 분해하가.• None kotlin data class는 자동으로 componentN으로 생성자의 순서대로 값을 가져올 수 있다.• None 08.05.data_class_sample.kt 파일을 다음과 같이 작성하자.• None 결과는 다음과 같다.• None data class는 순수하게 데이터를 담기 위한 클래스를 정의할때 유용하다.• None 내부적으로 toString, equals, hashCode, copy, componentN 등의 함수를 미리 작성되어 있기 때문에 반복적인 보일러플레이트 코드를 상당히 줄일 수 있다.• None 샘플 코드는: https://www.programiz.com/kotlin-programming/data-class 을 참조했다.• None sealed 클래스는 값이 제한된 세트 (제한된 계층구조)의 유형중 하나만 가질 수 있을때 사용된다.• None Expr 클래스는 베이스 클래스이다.• None Const와 Sum 은 Expr을 상속받은 객체인 것을 알 수 있다.• None eval 함수에서 Expr 를 파라미터로 받고, 각 자식 클래스의 타입에 따라 특정 일을 수행할때 when 구문을 이용하고 is 를 통해서 특정 클래스 타입일때 각 작업을 수행할 수 있게 된다.• None 이외의 값이 들어온다면 else 조건에 따라 IllegalArgumentException 을 반환하게 된다. 이 때 else는 필수이며, 없으면 오류가 난다. w• None when 조건식이 기타 케이스를 검출하지 못하기 때문이다.• None 위 코드에서 만약 Expr을 상속받는 새로운 자식 클래스를 작성한다면, 위 코드는 else에 걸리고, 원하지 않는 오류를 발생 시킬 수 있다.• None 이때에는 새로운 서브 클래스가 추가될때 컴파일러가 오류를 반환한다면, 누락되는 구현 없이 새로운 서브 클래스에 대한 대응 작업을 하게 된다.• None 이 때 사용하는 것이 sealed class 이다.• None sealed 를 지정하면 위 코드에서 else를 제거하고 좀더 제한적으로 클래스를 사용하도록 할 수 있다.Sealed 를 이용하여 바꾼 코드• None 이제 위 코드는 else가 없다.• None 왜냐하면 sealed 를 지정하여 Expr이 상속받는 클래스는 명확히 Const, Sum, NotANumber 로 규정했기 때문에 더이상의 서브 클래스가 없다고 선언했기 때문이다.• None 반드시 sealed 를 지정한 동일한 파일에 서브 클래스를 작성해야한다.• None sealed 클래스는 자체적으로 abstract 속성을 가진다. 그러므로 sealed 클래스는 직접 생성할 수 없다.• None 기본적으로 sealed class는 private 생성자를 가진다. sealed 클래스는 non-private 생성자를 가질 수 없다.Enum과 Sealed의 차이점• None Enum class와 Sealed class는 유사하게 보인다.• None enum 의 각 값들은 sealed class처럼 제한되어 사용된다.• None 차이점은 enum은 단지 단일 인스턴스만을 가지는 반면에, s
5/2/2024
logo
[Kotlin] DataClass와 Sealed Class 알아보기
• None 프로그램을 작성하다 보면, 오직 데이터를 실어 나르기 위한 객체를 만들어할 때가 있다.• None 이럴때 data class 를 사용하여 클래스를 생성하고, 데이터를 담을 수 있다.• None 위와 같이 data class 로 선언한다.• None Person은 데이터 클래스의 이름이다.• None data class는 name과 age 라는 속성을 가진다.• None 중요한 포인트는 data class는 copy(), equals(), hashCode(), toString() 에 대한 메소드를 자동으로 미리 구현되어 있다.• None 개발자가 직접 메소드를 작성할 필요가 없다.• None 기본 생성자는 무조건 1개 이상의 파라미터가 필요하다.• None 기본 생성자의 파라미터는 반드시 val(읽기 전용)이나 var(읽기-쓰기 가능) 를 가져야한다.• None 클래스는 open이 될수 없다. 즉, 상속이 불가능하다.• None abstract 도 될수 없다. 즉, 객체의 상속을 의도하지 않기 때문에 추상 클래스도 될 수 없다.• None inner이나 sealed 도 될수 없다.• None data class를 이제 만들어 보자.• None 08.01.data_class_sample.kt 파일을 다음과 같이 작성하자.• None 결과는 다음과 같다.• None 자동으로 toString 메소드가 구현되어 있으므로 println로 객체자체를 출력할때 Person(name=UncleBae, age=40) 이 출력되는 것을 확인할 수 있다.• None data class는 copy() 함수가 이미 구현되어 있다.• None 이를 이용하여 원래 data class로 부터 새로운 data class를 복사하고, 원하는 값을 변경할 수 있다.• None 08.02.data_class_sample.kt 파일을 다음과 같이 작성하자.• None 결과는 다음과 같다.• None 즉, copy 메소드를 이용하여 원래 값에서 이름만 바꾼 새로운 값을 생성하였다.• None hashCode() 는 객체 값을 이용하여 해시 코드를 생성한다. 즉, 값의 유니크성을 확인할 수 있도록 해주는 함수이다.• None equals() 는 객체 내부의 값이 동일한지 검사한다.• None 다음과 같이 08.03.data_class_sample.kt 파일을 다음과 같이 작성한다.• None 결과는 다음과 같다.• None 즉, person01에서 copy를 통해서객체를 그대로 복사했다. 이때 hashCode는 둘다 동일한 값을 가진다.• None 다만, 복사를 하고 해당 값을 변경하면 다른 값이 불러지게 된다.• None 데이터 객체로 부터 값을 조회할때 해당 데이터 클래스 값을 분해하여 반환 받을 수 있다.• None 이를 Destruction이라고 부른다.• None 08.04.data_class_sample.kt 파일을 다음과 같이 작성하자.• None 결과는 다음과 같다.componentN 형식으로 값 분해하가.• None kotlin data class는 자동으로 componentN으로 생성자의 순서대로 값을 가져올 수 있다.• None 08.05.data_class_sample.kt 파일을 다음과 같이 작성하자.• None 결과는 다음과 같다.• None data class는 순수하게 데이터를 담기 위한 클래스를 정의할때 유용하다.• None 내부적으로 toString, equals, hashCode, copy, componentN 등의 함수를 미리 작성되어 있기 때문에 반복적인 보일러플레이트 코드를 상당히 줄일 수 있다.• None 샘플 코드는: https://www.programiz.com/kotlin-programming/data-class 을 참조했다.• None sealed 클래스는 값이 제한된 세트 (제한된 계층구조)의 유형중 하나만 가질 수 있을때 사용된다.• None Expr 클래스는 베이스 클래스이다.• None Const와 Sum 은 Expr을 상속받은 객체인 것을 알 수 있다.• None eval 함수에서 Expr 를 파라미터로 받고, 각 자식 클래스의 타입에 따라 특정 일을 수행할때 when 구문을 이용하고 is 를 통해서 특정 클래스 타입일때 각 작업을 수행할 수 있게 된다.• None 이외의 값이 들어온다면 else 조건에 따라 IllegalArgumentException 을 반환하게 된다. 이 때 else는 필수이며, 없으면 오류가 난다. w• None when 조건식이 기타 케이스를 검출하지 못하기 때문이다.• None 위 코드에서 만약 Expr을 상속받는 새로운 자식 클래스를 작성한다면, 위 코드는 else에 걸리고, 원하지 않는 오류를 발생 시킬 수 있다.• None 이때에는 새로운 서브 클래스가 추가될때 컴파일러가 오류를 반환한다면, 누락되는 구현 없이 새로운 서브 클래스에 대한 대응 작업을 하게 된다.• None 이 때 사용하는 것이 sealed class 이다.• None sealed 를 지정하면 위 코드에서 else를 제거하고 좀더 제한적으로 클래스를 사용하도록 할 수 있다.Sealed 를 이용하여 바꾼 코드• None 이제 위 코드는 else가 없다.• None 왜냐하면 sealed 를 지정하여 Expr이 상속받는 클래스는 명확히 Const, Sum, NotANumber 로 규정했기 때문에 더이상의 서브 클래스가 없다고 선언했기 때문이다.• None 반드시 sealed 를 지정한 동일한 파일에 서브 클래스를 작성해야한다.• None sealed 클래스는 자체적으로 abstract 속성을 가진다. 그러므로 sealed 클래스는 직접 생성할 수 없다.• None 기본적으로 sealed class는 private 생성자를 가진다. sealed 클래스는 non-private 생성자를 가질 수 없다.Enum과 Sealed의 차이점• None Enum class와 Sealed class는 유사하게 보인다.• None enum 의 각 값들은 sealed class처럼 제한되어 사용된다.• None 차이점은 enum은 단지 단일 인스턴스만을 가지는 반면에, s
2024.05.02
emoji
좋아요
emoji
별로에요
logo
읽기 전용 설정으로 MySQL 이전하기
들어가며안녕하세요. VOOM Server Unit에서 LINE VOOM 서비스를 개발하고 있는 서용준입니다. LINE VOOM 서비스는 메인 콘텐츠인 포스트를 저장하기 위해 My...
5/2/2024
logo
읽기 전용 설정으로 MySQL 이전하기
들어가며안녕하세요. VOOM Server Unit에서 LINE VOOM 서비스를 개발하고 있는 서용준입니다. LINE VOOM 서비스는 메인 콘텐츠인 포스트를 저장하기 위해 My...
2024.05.02
emoji
좋아요
emoji
별로에요
logo
업무에 손쉽게 Golang 적용하기: 로케이션 코어팀 백엔드 개발자가 일하는 방식
안녕하세요! 로케이션 코어팀의 백엔드 개발자 샐리예요.로케이션 코어팀은 당근이 하이퍼로컬 앱으로 나아가는 데 기반이 되는 위치 기반 서비스와 지도 플랫폼을 개발하고 운영하는 팀이에요. 저는 팀 내에서 지도를 안정적으로 제공할 수 있는 파이프라인을 구축하고, 리소스를 관리할 수 있는 플랫폼을 개발하고 있어요.당근은 팀마다 서로 다른 기술 스택을 사용하고 있어요. 그 중에서도 로케이션 코어팀은 Go 언어로 서버를 개발하고 있는데요.저는 당근에 입사하기 이전에 Go를 사용해본 경험이 없었어요. 로케이션 코어팀에 합류하고 업무를 진행하면서 Go를 온몸으로 마주하게 되었죠.오늘은 그 과정에서 제가 마주했던 고민들을 공유해보려 해요. 더불어 로케이션 코어팀이 업무 효율성을 높이기 위해 Go를 어떠한 방식으로 사용하고 있는지, 그 방식이 저에게 어떻게 긍정적으로 작용했는지까지 함께 소개해볼게요! Golang이 궁금하셨던, 그리고 당근에서 Golang을 업무에 사용하는 방식이 궁금하셨던 분들에게 도움이 되는 글이기를 바라요  신입 Go-pher가 바라보는 Go 언어는..공식 홈페이지에서 Go를 소개하는 문장이에요.Build simple, secure, scalable systems with Go (Golang Official Catchphrase)Go는 다른 프로그래밍 언어에 비해 키워드 수가 적고 문법이 단순하여 배우기 쉽고, (simple) 컴파일러와 강타입(strongly-typed) 시스템을 기반으로 프로그램의 안전성 (secure)을 높일 수 있어요. 고루틴을 통해 동시성을 손쉽게 관리할 수 있어 대규모 서버와 분산 시스템에서 사용하기에도 유리해요. (scalable)이처럼 사용하기가 쉽고 자율성이 높다는 장점이 있지만 그만큼 낯설고 모호한 부분도 존재했어요.클래스가 없는 객체 지향 언어?Go언어는 보편적인 객체 지향 언어와 다른 성격을 띄고 있어요.놀랍게도, 클래스가 존재하지 않아요. 구조체(struct)를 사용하여 비슷한 역할을 만들어낼 수는 있지만 클래스처럼 메서드를 내장하지는 않아요. 대신 메서드를 정의한 인터페이스(interface)를 생성하고, 메서드가 해당 타입의 인스턴스에 속해 있는 것처럼 구현하여 다형성을 적용해요. 이때 func 키워드와 함수명 사이에 구조체를 선언하여 구조체와 메서드를 연결할 수 있는데, 이를 리시버(receiver)라고 불러요.type SampleInterface interface { SampleMethod()}type SampleStruct struct { Name string Data map[string]string}// 리시버로 구조체와 인터페이스의 메서드를 연결하여 다형성을 적용func (s SampleStruct) SampleMethod() { fmt.Println("implement sample method")}func (s SampleStruct) GetName() string { return s.Name}func main() { s := SampleStruct{Name: "name", Data: make(map[string]string)} var i SampleInterface i = s i.SampleMethod() // 인터페이스에 정의된 메서드 호출 fmt.Println(i.GetName()) // ERROR}개발 방법론의 유연함Go언어는 표준화된 개발 방법론이 서비스 개발에 강제되지 않아요. Go 자체의 컨벤션이나 여러 가이드들은 존재하지만, 사람마다 코드 작성 방식이 다를 수 있어요.특히 제가 입사를 했을 때인 약 1년 전까지만 해도 로케이션 코어팀 대부분의 팀원이 합류한지 3개월이 채 되지 않은 상태였고 운영 중인 프로젝트들도 각기 다른 맥락과 구조를 가지고 있었어요. 따라서 표준화된 구조를 가져가기보다는 각자 관리 중인 프로젝트의 특성에 맞게 유연한 개발을 진행하는 것이 더 효율적이었죠.프로젝트마다 geometry를 처리하기 위해 사용하는 라이브러리가 전부 달라요!하지만 그러다 보니 동일한 기능을 수행하는 코드 베이스임에도 불구하고 레포마다 각기 다른 라이브러리를 기반으로 구현되어 있어 히스토리를 파악하기 어렵거나 특정 프로젝트에서만 알 수 없는 버그가 발생하는 등의 문제도 있었어요.특정 프로젝트가 사용 중이던 라이브러리가 아카이브 되어버린 경우도 있었어요로직에 집중해야 하는데, 고민해야 할 것이 너무 많다?입사 당시 저는 모노레포로 관리 중인 저장소에 새로운 서버를 구성하는 과제를 2달 간 진행했는데요. 테크 스펙을 작성할 때 위에서 언급한 Go의 여러 특성들 때문에 아래와 같이 방법론적으로 고민해야 할 부분이 많았어요.그러다보니 로직 구성과 같은 정말 중요한 부분을 놓치고 있는 것 같다는 생각이 들기 시작했어요.우리 팀에서는 이런 방법을 사용했어요공유 가능한 Go 라이브러리 구현이러한 고민을 저만 하고 있던 것이 아니었던 것 같아요.왜냐하면 비슷한 맥락에서 코드의 일관성을 적정 레벨로 유지하며, 반복되는 작업을 최소화하여 생산성을 향상시키기 위해 팀 내에서 (일부 프로젝트에서만) 부분적으로 적용하고 있던 방식이 있었거든요.바로 공유 가능한 Go 라이브러리를 구현하고, 각 어플리케이션에서 필요에 따라 패키지나 모듈을 독립적으로 호출하여 사용하는 방식이에요.Fx라는 Go의 의존성 주입 라이브러리를 감싸 공유가 가능한 최소 단위의 모듈을 구현했어요. 구현된 모듈은 Database, Message Queue, Redis, Logger, gRPC Server 등 어플리케이션에서 필요한 여러 컴포넌트들을 제공해요.Fx는 Uber에서 개발한 Go 언어용 의존성 주입 라이브러리로 어플리케이션의 구성 요소들 사이의 의존성을 관리하고, hook에 정의한 lifecycle에 따라 객체를 생성 및 연결해주는 기능을 제공해줘요.아래와 같이 모듈을 생성할 수 있어요.독립적으로 호출할 fx.Module 변수를 정의해요.var Module = fx.Module("pg",2. fx.Provide 구문으로 module에 필요한 생성자들을 추가해요.var Module = fx.Module("server", fx.Provide(parseCon
go
5/2/2024
logo
업무에 손쉽게 Golang 적용하기: 로케이션 코어팀 백엔드 개발자가 일하는 방식
안녕하세요! 로케이션 코어팀의 백엔드 개발자 샐리예요.로케이션 코어팀은 당근이 하이퍼로컬 앱으로 나아가는 데 기반이 되는 위치 기반 서비스와 지도 플랫폼을 개발하고 운영하는 팀이에요. 저는 팀 내에서 지도를 안정적으로 제공할 수 있는 파이프라인을 구축하고, 리소스를 관리할 수 있는 플랫폼을 개발하고 있어요.당근은 팀마다 서로 다른 기술 스택을 사용하고 있어요. 그 중에서도 로케이션 코어팀은 Go 언어로 서버를 개발하고 있는데요.저는 당근에 입사하기 이전에 Go를 사용해본 경험이 없었어요. 로케이션 코어팀에 합류하고 업무를 진행하면서 Go를 온몸으로 마주하게 되었죠.오늘은 그 과정에서 제가 마주했던 고민들을 공유해보려 해요. 더불어 로케이션 코어팀이 업무 효율성을 높이기 위해 Go를 어떠한 방식으로 사용하고 있는지, 그 방식이 저에게 어떻게 긍정적으로 작용했는지까지 함께 소개해볼게요! Golang이 궁금하셨던, 그리고 당근에서 Golang을 업무에 사용하는 방식이 궁금하셨던 분들에게 도움이 되는 글이기를 바라요  신입 Go-pher가 바라보는 Go 언어는..공식 홈페이지에서 Go를 소개하는 문장이에요.Build simple, secure, scalable systems with Go (Golang Official Catchphrase)Go는 다른 프로그래밍 언어에 비해 키워드 수가 적고 문법이 단순하여 배우기 쉽고, (simple) 컴파일러와 강타입(strongly-typed) 시스템을 기반으로 프로그램의 안전성 (secure)을 높일 수 있어요. 고루틴을 통해 동시성을 손쉽게 관리할 수 있어 대규모 서버와 분산 시스템에서 사용하기에도 유리해요. (scalable)이처럼 사용하기가 쉽고 자율성이 높다는 장점이 있지만 그만큼 낯설고 모호한 부분도 존재했어요.클래스가 없는 객체 지향 언어?Go언어는 보편적인 객체 지향 언어와 다른 성격을 띄고 있어요.놀랍게도, 클래스가 존재하지 않아요. 구조체(struct)를 사용하여 비슷한 역할을 만들어낼 수는 있지만 클래스처럼 메서드를 내장하지는 않아요. 대신 메서드를 정의한 인터페이스(interface)를 생성하고, 메서드가 해당 타입의 인스턴스에 속해 있는 것처럼 구현하여 다형성을 적용해요. 이때 func 키워드와 함수명 사이에 구조체를 선언하여 구조체와 메서드를 연결할 수 있는데, 이를 리시버(receiver)라고 불러요.type SampleInterface interface { SampleMethod()}type SampleStruct struct { Name string Data map[string]string}// 리시버로 구조체와 인터페이스의 메서드를 연결하여 다형성을 적용func (s SampleStruct) SampleMethod() { fmt.Println("implement sample method")}func (s SampleStruct) GetName() string { return s.Name}func main() { s := SampleStruct{Name: "name", Data: make(map[string]string)} var i SampleInterface i = s i.SampleMethod() // 인터페이스에 정의된 메서드 호출 fmt.Println(i.GetName()) // ERROR}개발 방법론의 유연함Go언어는 표준화된 개발 방법론이 서비스 개발에 강제되지 않아요. Go 자체의 컨벤션이나 여러 가이드들은 존재하지만, 사람마다 코드 작성 방식이 다를 수 있어요.특히 제가 입사를 했을 때인 약 1년 전까지만 해도 로케이션 코어팀 대부분의 팀원이 합류한지 3개월이 채 되지 않은 상태였고 운영 중인 프로젝트들도 각기 다른 맥락과 구조를 가지고 있었어요. 따라서 표준화된 구조를 가져가기보다는 각자 관리 중인 프로젝트의 특성에 맞게 유연한 개발을 진행하는 것이 더 효율적이었죠.프로젝트마다 geometry를 처리하기 위해 사용하는 라이브러리가 전부 달라요!하지만 그러다 보니 동일한 기능을 수행하는 코드 베이스임에도 불구하고 레포마다 각기 다른 라이브러리를 기반으로 구현되어 있어 히스토리를 파악하기 어렵거나 특정 프로젝트에서만 알 수 없는 버그가 발생하는 등의 문제도 있었어요.특정 프로젝트가 사용 중이던 라이브러리가 아카이브 되어버린 경우도 있었어요로직에 집중해야 하는데, 고민해야 할 것이 너무 많다?입사 당시 저는 모노레포로 관리 중인 저장소에 새로운 서버를 구성하는 과제를 2달 간 진행했는데요. 테크 스펙을 작성할 때 위에서 언급한 Go의 여러 특성들 때문에 아래와 같이 방법론적으로 고민해야 할 부분이 많았어요.그러다보니 로직 구성과 같은 정말 중요한 부분을 놓치고 있는 것 같다는 생각이 들기 시작했어요.우리 팀에서는 이런 방법을 사용했어요공유 가능한 Go 라이브러리 구현이러한 고민을 저만 하고 있던 것이 아니었던 것 같아요.왜냐하면 비슷한 맥락에서 코드의 일관성을 적정 레벨로 유지하며, 반복되는 작업을 최소화하여 생산성을 향상시키기 위해 팀 내에서 (일부 프로젝트에서만) 부분적으로 적용하고 있던 방식이 있었거든요.바로 공유 가능한 Go 라이브러리를 구현하고, 각 어플리케이션에서 필요에 따라 패키지나 모듈을 독립적으로 호출하여 사용하는 방식이에요.Fx라는 Go의 의존성 주입 라이브러리를 감싸 공유가 가능한 최소 단위의 모듈을 구현했어요. 구현된 모듈은 Database, Message Queue, Redis, Logger, gRPC Server 등 어플리케이션에서 필요한 여러 컴포넌트들을 제공해요.Fx는 Uber에서 개발한 Go 언어용 의존성 주입 라이브러리로 어플리케이션의 구성 요소들 사이의 의존성을 관리하고, hook에 정의한 lifecycle에 따라 객체를 생성 및 연결해주는 기능을 제공해줘요.아래와 같이 모듈을 생성할 수 있어요.독립적으로 호출할 fx.Module 변수를 정의해요.var Module = fx.Module("pg",2. fx.Provide 구문으로 module에 필요한 생성자들을 추가해요.var Module = fx.Module("server", fx.Provide(parseCon
2024.05.02
go
emoji
좋아요
emoji
별로에요
logo
배민선물하기 AI 메시지 제작기: 생성 AI가 센스 있는 선물 메시지를 대신 쓰기까지
배민선물하기 AI 메시지 제작기: 생성 AI가 센스 있는 선물 메시지를 대신 쓰기까지여러분은 생성 AI를 적용한 서비스를 만들어본 적이 있으신가요? 배민선물하기팀에서는 만우절을 맞이하여 배민선물하기 서비스 내 생성 AI를 활용한 ‘AI 메시지’ 기능을 오픈했습니다. AI 메시지는 배달의민족 앱 내 선물하기 서비스에서 선물할 때, 선택한 카드에 어울리는 메시지를 AI가 대신 작성해주는 기능입니다. AI 메시지는 만우절을 맞이하여 유머러스한 메시지를 추천해주었으며, 3월 28일부터 4월 1일까지 서비스되었습니다. 배민선물하기에서 AI 메시지를 만들게 된 이유배민선물하기는 배달의민족 앱에서 "밥은 먹었니?"와 같이 안부를 전하며 마음을 담은 선물을 할 수 있는 서비스입니다. 다른 선물하기 서비스와는 다르게 선물 의도에 맞게 특별한 카드를 고르고 직접 메시지를 작성해서 좀 더 마음이 담긴 선물을 할 수 있는 특징이 있습니다. 특히 배민선물하기는 선물한 사람의 따뜻한 마음을 받는 사람에게 전달할 수 있는 선물 경험을 만들기 위해 노력하며, 메시지를 작성하는 행위를 마음을 전달하는 중요한 수단으로 생각하고 있습니다. 그래서 생성 AI를 배민선물하기에 접목하는 서비스 아이디어를 고려할 때 우리는 메시지 작성에 어려움을 겪는 고객을 돕는 것에 가치를 두고 문제를 해결하고자 했습니다. 초창기 배민선물하기 서비스에서는 고객이 선물을 선택하면 기본적으로 제공하던 메시지가 있었는데, 서비스를 업데이트하면서 기본메시지를 더 이상 제공하지 않아 아쉽다는 고객의 의견이 종종 있었습니다. 선물과 카드를 고르고 나서 메시지를 작성하려고 할 때 어떤 메시지를 보낼 지 고민된다는 고객도 있었습니다.선물 메시지 작성에 어려움을 겪는 고객을 위해 AI가 대신 메시지를 써준다면 어떨까요? 메시지 작성을 고민하는 시간이 줄어들면 좀 더 편리한 선물 경험이 되지 않을까요? 이 질문과 기대로 AI 메시지 프로젝트가 시작되었습니다. 배민선물하기에는 다양한 카드가 있다는 점이 강점이지만 현실적으로 카드에 어울리는 메시지를 사람이 모두 작성하고 입력하기에는 어려움이 있습니다. 그래서 생성 AI가 사람 대신 각 카드에 어울리는 다양한 메시지를 메시지를 생성하게 하고, 고객은 카드를 고른 후 "AI 메시지로 대신 써주세요" 버튼을 눌러 AI가 추천해주는 여러 메시지 중에 마음에 드는 메시지를 선택하도록 하였습니다.금쪽이 GPT를 훈련시키는 솔루션 3단계Step1. 우리 (에이)아이의 성격 정의하기Chat GPT(OpenAI에서 개발한 GPT-3.5와 GPT-4를 기반으로 하는 대화형 인공지능 서비스)를 이용하여 선물 메시지를 생성하기로 결정한 다음에 가장 먼저 한 일은 AI의 성격(아이덴티티)을 정의하는 것이었습니다. 대화형 AI에게서 원하는 답을 얻기 위해 가장 중요한 것이 바로 ‘역할 부여’이기 때문입니다. 만우절을 맞이하여 AI가 장난스러운 농담 메시지를 대신 생성해주는 것을 기대하며, ‘재기 발랄한 농담으로 사람들을 웃기는 코미디언’이란 직업뿐만 아니라, 기본적인 말투를 구체적으로
5/1/2024
logo
배민선물하기 AI 메시지 제작기: 생성 AI가 센스 있는 선물 메시지를 대신 쓰기까지
배민선물하기 AI 메시지 제작기: 생성 AI가 센스 있는 선물 메시지를 대신 쓰기까지여러분은 생성 AI를 적용한 서비스를 만들어본 적이 있으신가요? 배민선물하기팀에서는 만우절을 맞이하여 배민선물하기 서비스 내 생성 AI를 활용한 ‘AI 메시지’ 기능을 오픈했습니다. AI 메시지는 배달의민족 앱 내 선물하기 서비스에서 선물할 때, 선택한 카드에 어울리는 메시지를 AI가 대신 작성해주는 기능입니다. AI 메시지는 만우절을 맞이하여 유머러스한 메시지를 추천해주었으며, 3월 28일부터 4월 1일까지 서비스되었습니다. 배민선물하기에서 AI 메시지를 만들게 된 이유배민선물하기는 배달의민족 앱에서 "밥은 먹었니?"와 같이 안부를 전하며 마음을 담은 선물을 할 수 있는 서비스입니다. 다른 선물하기 서비스와는 다르게 선물 의도에 맞게 특별한 카드를 고르고 직접 메시지를 작성해서 좀 더 마음이 담긴 선물을 할 수 있는 특징이 있습니다. 특히 배민선물하기는 선물한 사람의 따뜻한 마음을 받는 사람에게 전달할 수 있는 선물 경험을 만들기 위해 노력하며, 메시지를 작성하는 행위를 마음을 전달하는 중요한 수단으로 생각하고 있습니다. 그래서 생성 AI를 배민선물하기에 접목하는 서비스 아이디어를 고려할 때 우리는 메시지 작성에 어려움을 겪는 고객을 돕는 것에 가치를 두고 문제를 해결하고자 했습니다. 초창기 배민선물하기 서비스에서는 고객이 선물을 선택하면 기본적으로 제공하던 메시지가 있었는데, 서비스를 업데이트하면서 기본메시지를 더 이상 제공하지 않아 아쉽다는 고객의 의견이 종종 있었습니다. 선물과 카드를 고르고 나서 메시지를 작성하려고 할 때 어떤 메시지를 보낼 지 고민된다는 고객도 있었습니다.선물 메시지 작성에 어려움을 겪는 고객을 위해 AI가 대신 메시지를 써준다면 어떨까요? 메시지 작성을 고민하는 시간이 줄어들면 좀 더 편리한 선물 경험이 되지 않을까요? 이 질문과 기대로 AI 메시지 프로젝트가 시작되었습니다. 배민선물하기에는 다양한 카드가 있다는 점이 강점이지만 현실적으로 카드에 어울리는 메시지를 사람이 모두 작성하고 입력하기에는 어려움이 있습니다. 그래서 생성 AI가 사람 대신 각 카드에 어울리는 다양한 메시지를 메시지를 생성하게 하고, 고객은 카드를 고른 후 "AI 메시지로 대신 써주세요" 버튼을 눌러 AI가 추천해주는 여러 메시지 중에 마음에 드는 메시지를 선택하도록 하였습니다.금쪽이 GPT를 훈련시키는 솔루션 3단계Step1. 우리 (에이)아이의 성격 정의하기Chat GPT(OpenAI에서 개발한 GPT-3.5와 GPT-4를 기반으로 하는 대화형 인공지능 서비스)를 이용하여 선물 메시지를 생성하기로 결정한 다음에 가장 먼저 한 일은 AI의 성격(아이덴티티)을 정의하는 것이었습니다. 대화형 AI에게서 원하는 답을 얻기 위해 가장 중요한 것이 바로 ‘역할 부여’이기 때문입니다. 만우절을 맞이하여 AI가 장난스러운 농담 메시지를 대신 생성해주는 것을 기대하며, ‘재기 발랄한 농담으로 사람들을 웃기는 코미디언’이란 직업뿐만 아니라, 기본적인 말투를 구체적으로
2024.05.01
emoji
좋아요
emoji
별로에요
logo
CatLIP: 2.7배 빠른 범주 학습(Categorical) 기법에 대한 연구(feat. Apple)
Apple이 매주 연구 결과들을 공개하고 있는데, 뭔가 반가우면서도 어색한 미묘한 기분이네요😲요즘 Apple은 Visual Encoder에 진심인건지, 작년 말에는 CLIP보다 작은 크기로 더 나은 성능을 보이는 MobileCLIP에 대한 연구를 공개한데 이어,이번에는 Web Scale의 이미지-텍스트 쌍(Image-Text Pair) 데이터들을 더 빠르게 사전학습하는 CatLIP에 대한 연구를 공개했습니다.CLIP의 대조 학습(Contrastive Learning) 대신 범주 학습(Categorical Learning)을 사용하여 성능은 비슷하면서도 속도는 2.7배 가량 빠르다고 하는데요,심지어 사전 학습 모델의 가중치와 함께 모델 코드의 공개도 언급하였습니다.CatLIP: 대규모 이미지-텍스트 데이터로 2.7배 빠른 사전학습 및 CLIP 수준의 인식 정확도를 달성Apple이 이번에 공개한 CatLIP(Categorical Loss for Image-text Pre-training)은 OpenAI에서 소개한 CLIP(Contrastive Language-Image Pretraining)과 비교하여약 2.7배 빠른 사전 학습 속도를 보이는 새로운 방법입니다.OpenAI가 CLIP에서 사용한 Constrastive Pre-Training 기법 (출처: OpenAI 홈페이지)OpenAI가 CLIP에서 사용한 대조학습(Contrastive Learning) 기법은 엄청난 규모의 이미지들을 사용한 사전학습(Pre-training) 방법입니다.이전의 지도 학습(Supervised Learning)에서는 학습 데이터로 사용하는 이미지가 어떠한 것인지를 나타내는 레이블(Label, 정답)이 있어야 하기 때문에 대량의 데이터셋을 생성하기가 쉽지 않았습니다.OpenAI에서는 이를 해결하기 위해 인터넷에 공개된 다양한 이미지와 이를 설명하는 텍스트(명시적인 설명 또는 설명으로 추정되는 텍스트 등)를 모은 다음,사전 학습 시 하나의 배치 내의 여러개의 쌍에 대해서 유사성을 학습하였습니다.즉, 위 그림과 같이 이미지와 텍스트를 각각 인코더에 통과시켜 임베딩(Embedding)을 추출한 뒤,학습 시 사용하는 하나의 배치(Batch) 내에서 서로 같은 Image-Text 쌍에 대해서는 유사도가 높도록(Positive Sample, 위 그림의 I-T Matrix의 대각 성분),서로 다른 Image-Text 쌍에 대해서는 유사도가 낮도록(Negative Samples, 위 그림의 I-T Matrix의 대각 성분을 제외한 나머지) 학습하는 방식입니다.이러한 대조 학습 방식은 잡음(noise)이 많은 대량의 데이터셋을 처리하는데 있어 획기적인 성과를 보였지만,이미지와 텍스트 임베딩 간의 광범위한 쌍별(pairwise) 유사성을 확인하는 과정에서 다소 많은 연산 작업이 필요합니다.이를 위해 모델의 일부를 최적화하거나 전처리된 인코더를 사용하는 방법들이 제안되었지만, CatLIP에서는 아예 이러한 과정을 다르게 접근하였습니다.CatLIP은 CLIP에서 사용했던 전처리 과정을 대조적 방법(Contrastive)이 아닌 분류 작업(Categorical)으로 재구성함으로써,대조 학습(Contrastive Learning) 시에 사용하던 유사도 계산(Similarity Comptation) 과정을 생략하였습니다.이를 통해 CatLIP의 사전학습 속도가 CLIP보다 2.7배 가량 빠르게 개선되었으며, 적용하는 작업(Downstream Task)에서의 정확도는 비슷하게 유지함을 보였습니다.CatLIP의 주요 아이디어• None 새로운 사전 학습 접근 방식: CatLIP은 이미지-텍스트 데이터의 사전 학습을 분류 작업으로 처리하여 사전 학습 단계를 가속화하는 방법을 제시합니다. 이 접근 방식은 이 분야에서 처음 시도되는 것으로, 일반적으로 CLIP에서 볼 수 있는 대조적 학습 방법과는 다르게, CatLIP은 이미지-텍스트 전처리를 다중 레이블 분류 작업으로 취급합니다. 이러한 접근 방식을 통해 텍스트에서 파생된 레이블을 이미지에 직접 연결하여 학습 과정을 단순화합니다.• None 스케일링 향상: 소개된 방법인 CatLIP은 데이터 및 모델 스케일링 시 정확도를 향상시킵니다. 특히 작은 규모의 이미지-텍스트 데이터셋에서 CatLIP 하에 긴 학습 기간 동안 CLIP을 사용할 때보다 더 나은 성능을 보입니다.• None 효율성 및 속도: 사전 학습 시 각 이미지-텍스트 쌍(pair)들 간의 비교를 하지 않아도 됨으로써, CatLIP은 CLIP 대비 연산 오버헤드를 줄일 수 있었습니다. 이를 통해 대규모 데이터셋에서 모델 전처리 속도를 CLIP 대비 2.7배 향상시켰습니다.• None 전이 학습: 전통적인 전이 학습 접근 방식은 사전 훈련된 모델 백본을 사용하고 분류기(Classifier)의 가중치를 새로 초기화하는 것이었습니다. CatLIP은 타겟 작업 레이블과 관련된 임베딩을 분류 계층에서 추출할 수 있어, 이렇게 추출한 임베딩을 직접 새 작업의 분류 계층에 초기화하는 것을 가능하게 합니다. 이는 새로운 작업에서 레이블로 사용할 수 있어 효율적인 전이학습이 가능합니다.• None 광범위한 검증: 논문은 객체 탐지 및 의미론적 분할과 같은 다양한 하류 작업에 걸쳐 광범위한 실험을 자세히 설명하며, CatLIP이 학습한 표현이 CLIP이 학습한 표현과 비슷한 성능을 보임을 보여줍니다. 특히, CatLIP을 사용한 비전 트랜스포머(ViT B/16)는 COCO 데이터셋에서 평균 정밀도 점수 49.9를 달성하여 CLIP의 성능과 동등하지만 사전 학습 시간은 2.7배 빠르다는 점을 강조합니다.CatLIP은 Vision Transformer(ViT)를 이미지 인코더로 사용하여 이미지로부터 특징을 추출합니다.이 과정에서 ViT는 이미지를 패치로 나누고, 이 패치들을 시퀀스처럼 처리하여 각 패치의 특징을 학습합니다.또한, 앞에서 설명하였던 것처럼 사전 학습을 이미지에 대한 텍스트 레이블을 분류(Classification)하는 작업으로 보고 접근합니다.이를 위해 학습 시에는 텍스트 캡션으로부터 명사들을 추출한 뒤,이를 WordNet을
4/30/2024
logo
CatLIP: 2.7배 빠른 범주 학습(Categorical) 기법에 대한 연구(feat. Apple)
Apple이 매주 연구 결과들을 공개하고 있는데, 뭔가 반가우면서도 어색한 미묘한 기분이네요😲요즘 Apple은 Visual Encoder에 진심인건지, 작년 말에는 CLIP보다 작은 크기로 더 나은 성능을 보이는 MobileCLIP에 대한 연구를 공개한데 이어,이번에는 Web Scale의 이미지-텍스트 쌍(Image-Text Pair) 데이터들을 더 빠르게 사전학습하는 CatLIP에 대한 연구를 공개했습니다.CLIP의 대조 학습(Contrastive Learning) 대신 범주 학습(Categorical Learning)을 사용하여 성능은 비슷하면서도 속도는 2.7배 가량 빠르다고 하는데요,심지어 사전 학습 모델의 가중치와 함께 모델 코드의 공개도 언급하였습니다.CatLIP: 대규모 이미지-텍스트 데이터로 2.7배 빠른 사전학습 및 CLIP 수준의 인식 정확도를 달성Apple이 이번에 공개한 CatLIP(Categorical Loss for Image-text Pre-training)은 OpenAI에서 소개한 CLIP(Contrastive Language-Image Pretraining)과 비교하여약 2.7배 빠른 사전 학습 속도를 보이는 새로운 방법입니다.OpenAI가 CLIP에서 사용한 Constrastive Pre-Training 기법 (출처: OpenAI 홈페이지)OpenAI가 CLIP에서 사용한 대조학습(Contrastive Learning) 기법은 엄청난 규모의 이미지들을 사용한 사전학습(Pre-training) 방법입니다.이전의 지도 학습(Supervised Learning)에서는 학습 데이터로 사용하는 이미지가 어떠한 것인지를 나타내는 레이블(Label, 정답)이 있어야 하기 때문에 대량의 데이터셋을 생성하기가 쉽지 않았습니다.OpenAI에서는 이를 해결하기 위해 인터넷에 공개된 다양한 이미지와 이를 설명하는 텍스트(명시적인 설명 또는 설명으로 추정되는 텍스트 등)를 모은 다음,사전 학습 시 하나의 배치 내의 여러개의 쌍에 대해서 유사성을 학습하였습니다.즉, 위 그림과 같이 이미지와 텍스트를 각각 인코더에 통과시켜 임베딩(Embedding)을 추출한 뒤,학습 시 사용하는 하나의 배치(Batch) 내에서 서로 같은 Image-Text 쌍에 대해서는 유사도가 높도록(Positive Sample, 위 그림의 I-T Matrix의 대각 성분),서로 다른 Image-Text 쌍에 대해서는 유사도가 낮도록(Negative Samples, 위 그림의 I-T Matrix의 대각 성분을 제외한 나머지) 학습하는 방식입니다.이러한 대조 학습 방식은 잡음(noise)이 많은 대량의 데이터셋을 처리하는데 있어 획기적인 성과를 보였지만,이미지와 텍스트 임베딩 간의 광범위한 쌍별(pairwise) 유사성을 확인하는 과정에서 다소 많은 연산 작업이 필요합니다.이를 위해 모델의 일부를 최적화하거나 전처리된 인코더를 사용하는 방법들이 제안되었지만, CatLIP에서는 아예 이러한 과정을 다르게 접근하였습니다.CatLIP은 CLIP에서 사용했던 전처리 과정을 대조적 방법(Contrastive)이 아닌 분류 작업(Categorical)으로 재구성함으로써,대조 학습(Contrastive Learning) 시에 사용하던 유사도 계산(Similarity Comptation) 과정을 생략하였습니다.이를 통해 CatLIP의 사전학습 속도가 CLIP보다 2.7배 가량 빠르게 개선되었으며, 적용하는 작업(Downstream Task)에서의 정확도는 비슷하게 유지함을 보였습니다.CatLIP의 주요 아이디어• None 새로운 사전 학습 접근 방식: CatLIP은 이미지-텍스트 데이터의 사전 학습을 분류 작업으로 처리하여 사전 학습 단계를 가속화하는 방법을 제시합니다. 이 접근 방식은 이 분야에서 처음 시도되는 것으로, 일반적으로 CLIP에서 볼 수 있는 대조적 학습 방법과는 다르게, CatLIP은 이미지-텍스트 전처리를 다중 레이블 분류 작업으로 취급합니다. 이러한 접근 방식을 통해 텍스트에서 파생된 레이블을 이미지에 직접 연결하여 학습 과정을 단순화합니다.• None 스케일링 향상: 소개된 방법인 CatLIP은 데이터 및 모델 스케일링 시 정확도를 향상시킵니다. 특히 작은 규모의 이미지-텍스트 데이터셋에서 CatLIP 하에 긴 학습 기간 동안 CLIP을 사용할 때보다 더 나은 성능을 보입니다.• None 효율성 및 속도: 사전 학습 시 각 이미지-텍스트 쌍(pair)들 간의 비교를 하지 않아도 됨으로써, CatLIP은 CLIP 대비 연산 오버헤드를 줄일 수 있었습니다. 이를 통해 대규모 데이터셋에서 모델 전처리 속도를 CLIP 대비 2.7배 향상시켰습니다.• None 전이 학습: 전통적인 전이 학습 접근 방식은 사전 훈련된 모델 백본을 사용하고 분류기(Classifier)의 가중치를 새로 초기화하는 것이었습니다. CatLIP은 타겟 작업 레이블과 관련된 임베딩을 분류 계층에서 추출할 수 있어, 이렇게 추출한 임베딩을 직접 새 작업의 분류 계층에 초기화하는 것을 가능하게 합니다. 이는 새로운 작업에서 레이블로 사용할 수 있어 효율적인 전이학습이 가능합니다.• None 광범위한 검증: 논문은 객체 탐지 및 의미론적 분할과 같은 다양한 하류 작업에 걸쳐 광범위한 실험을 자세히 설명하며, CatLIP이 학습한 표현이 CLIP이 학습한 표현과 비슷한 성능을 보임을 보여줍니다. 특히, CatLIP을 사용한 비전 트랜스포머(ViT B/16)는 COCO 데이터셋에서 평균 정밀도 점수 49.9를 달성하여 CLIP의 성능과 동등하지만 사전 학습 시간은 2.7배 빠르다는 점을 강조합니다.CatLIP은 Vision Transformer(ViT)를 이미지 인코더로 사용하여 이미지로부터 특징을 추출합니다.이 과정에서 ViT는 이미지를 패치로 나누고, 이 패치들을 시퀀스처럼 처리하여 각 패치의 특징을 학습합니다.또한, 앞에서 설명하였던 것처럼 사전 학습을 이미지에 대한 텍스트 레이블을 분류(Classification)하는 작업으로 보고 접근합니다.이를 위해 학습 시에는 텍스트 캡션으로부터 명사들을 추출한 뒤,이를 WordNet을
2024.04.30
emoji
좋아요
emoji
별로에요
logo
Rockstar 프로그래밍 언어 알아보기: 코드로 노래 가사를 쓸 수 있다면?
안녕하세요 데보션 영 3기 5CEAN에서 활동 중인 권지원이라고 합니다.저는 종종 노래방에서 Linkin Park의 Given Up을 부르면서 스트레스를 풀곤 합니다. 코딩을 할 때는 유명한 락 밴드들의 노래를 하루종일 틀어놓고요.노래를 들으며 코딩을 하다 보면 이런 생각이 들 수 있습니다. 프로그래밍 언어와 노래는 아무런 연관이 없을까?"Just call my name, 'cause I'll hear you scream Master, Master"란 Metallica의 Master of Puppets 노래 가사를 보고, 프로그래밍 언어의 컴파일러를 생각해보는 겁니다.call에게 print 란 키워드 역할을 주고, my name이 변수 이름이라고 가정하면?공백을 기준으로 파싱하고, 특별한 규칙을 적용할 키워드를 정의한다면? 흥미로운 언어가 만들어지지 않을까?실제로 이런 농담 같은 생각에서 만들어진 언어가 존재합니다. 바로 오늘 소개할 프로그래밍 언어인 Rockstar입니다.The Art of Code 란 컨퍼런스를 보신 분 계신가요? 코드의 예술적인 면을 보여주는 아주 재미있는 강연입니다.그중에서도 제 눈을 이끈건 영상 말미에 소개된 강연자 Dylan Beattie가 제작한 Rockstar란 언어입니다.프로그래밍 언어 자체로도 아름다울 수 있다는 것을 깨닫게 해주었죠. 예제 코드를 한번 볼까요?해당 코드는 Rockstar로 쓰인 Fizzbuzz입니다.코드에 리듬만 붙이면 그럴싸한 노래가 될 것 같습니다.Rockstar 언어의 핵심 가치인 "If you can't sing it, you can't have it"이 드러난 코드입니다.그렇다면 Rockstar 언어는 어떻게, 그리고 왜 만들어지게 된 것인지 알아보겠습니다.Rockstar란 메탈 가사처럼 보이는 프로그램을 작성할 수 있는 동적 타입 컴퓨터 프로그래밍 언어입니다.Paul Stovell의 트윗에서 영감을 받아 Dylan Beattie에 의해 만들어진 언어로, 1980년대 하드 록과 파워 발라드 가사 컨벤션에 큰 영향을 받았습니다.Rockstar 언어는 왜 만들어진 걸까요? Rockstar 개발자에 따르면 해당 언어는 순전히 농담에서 출발한 언어라고 합니다.그리고 노래 가사를 컴파일하는 것이 멋지고 'CERTFIED ROCSTAR DEVELOPER'라고 스티커를 붙일 수도 있다는 점이 장점인 언어라 홍보하고, 그 이외에 기능적인 장점은 일절 언급하지 않습니다.이것도 이 언어의 매력적인 점이라고 볼 수 있죠 😄언어의 주요 특징으로는 거의 모든 코드가 문자라는 것입니다.Rockstar의 주요 문법은 Hello World 코드 샘플을 분석해보며 훑어보겠습니다.해당 Rockstar 코드를 실행하면 콘솔 창에 Hello World가 출력됩니다. 엄청 길지만 참 멋진 코드입니다.Rockstar에서는 주석을 소괄호로 처리합니다.이번 게시글에서는 가볍게 알아보는 자리이므로 예제에 주석으로 코드가 의미하는 바를 분석해놓았고, 예제 밑에 주요 문법 특징을 적어보았습니다.• None Rockstar만의 독특한 언어 기능.• None 개발자 내면 깊숙한 곳의 공포, 두려움을 표현하도록 도와줍니다.• None• None 변수 이름 + 키워드 is, are, was, were 뒤에 오는 해당 줄의 코드는 모두 10진수로 취급됩니다.• None 따라서 The prize == 7이 됩니다.• None Rockstar에서 문자와 숫자는 유니코드를 기준으로 변환됩니다.• None with 뒤에 있는 원소를 삽입• None 변수 이름은 case insensitive이기 때문에 The dawn과 the dawn은 모두 같은 변수입니다.Rockstar 깃헙 레포지토리에 있는 예제를 이용해 "Hello World"를 출력해보았습니다.단순히 문자열만 출력하는 방법도 있지만 Rockstar 언어의 특징을 살려 "Hello World"를 출력한 코드를 보는 것이 더 의미있을 것 같아서 가져왔습니다.가끔 공부를 하다 보면, 이런저런 것들을 따지느라 프로그래밍 언어 자체의 매력을 잊어버릴 때가 있습니다.저는 그럴 때마다 재미난 것들을 탐구하며 시간을 보내곤 합니다. 이번 탐구 활동의 결과물인 프로그래밍 언어 Rockstar를 소개글을 작성해보았습니다.거의 처음 작성해보는 게시글이라 글의 전개나 글이 어색한 면이 없지 않아 있지만, 제가 해당 언어를 보고 느꼈던 즐거움이 전해졌으면 좋겠습니다.최근에는 상대적으로 친숙한 언어인 Java로 Rockstar 컴파일러를 조금씩 제작하고 있는데, 생각보다 쉽지 않네요 🥲모두 힘들더라도 🤘Rock n' Roll 🤘하며 이겨냅시다. 화이팅 !!앞서 언급한 The Art of Code 컨퍼런스 번역본에 관심 있으신 분 계신가요?
4/30/2024
logo
Rockstar 프로그래밍 언어 알아보기: 코드로 노래 가사를 쓸 수 있다면?
안녕하세요 데보션 영 3기 5CEAN에서 활동 중인 권지원이라고 합니다.저는 종종 노래방에서 Linkin Park의 Given Up을 부르면서 스트레스를 풀곤 합니다. 코딩을 할 때는 유명한 락 밴드들의 노래를 하루종일 틀어놓고요.노래를 들으며 코딩을 하다 보면 이런 생각이 들 수 있습니다. 프로그래밍 언어와 노래는 아무런 연관이 없을까?"Just call my name, 'cause I'll hear you scream Master, Master"란 Metallica의 Master of Puppets 노래 가사를 보고, 프로그래밍 언어의 컴파일러를 생각해보는 겁니다.call에게 print 란 키워드 역할을 주고, my name이 변수 이름이라고 가정하면?공백을 기준으로 파싱하고, 특별한 규칙을 적용할 키워드를 정의한다면? 흥미로운 언어가 만들어지지 않을까?실제로 이런 농담 같은 생각에서 만들어진 언어가 존재합니다. 바로 오늘 소개할 프로그래밍 언어인 Rockstar입니다.The Art of Code 란 컨퍼런스를 보신 분 계신가요? 코드의 예술적인 면을 보여주는 아주 재미있는 강연입니다.그중에서도 제 눈을 이끈건 영상 말미에 소개된 강연자 Dylan Beattie가 제작한 Rockstar란 언어입니다.프로그래밍 언어 자체로도 아름다울 수 있다는 것을 깨닫게 해주었죠. 예제 코드를 한번 볼까요?해당 코드는 Rockstar로 쓰인 Fizzbuzz입니다.코드에 리듬만 붙이면 그럴싸한 노래가 될 것 같습니다.Rockstar 언어의 핵심 가치인 "If you can't sing it, you can't have it"이 드러난 코드입니다.그렇다면 Rockstar 언어는 어떻게, 그리고 왜 만들어지게 된 것인지 알아보겠습니다.Rockstar란 메탈 가사처럼 보이는 프로그램을 작성할 수 있는 동적 타입 컴퓨터 프로그래밍 언어입니다.Paul Stovell의 트윗에서 영감을 받아 Dylan Beattie에 의해 만들어진 언어로, 1980년대 하드 록과 파워 발라드 가사 컨벤션에 큰 영향을 받았습니다.Rockstar 언어는 왜 만들어진 걸까요? Rockstar 개발자에 따르면 해당 언어는 순전히 농담에서 출발한 언어라고 합니다.그리고 노래 가사를 컴파일하는 것이 멋지고 'CERTFIED ROCSTAR DEVELOPER'라고 스티커를 붙일 수도 있다는 점이 장점인 언어라 홍보하고, 그 이외에 기능적인 장점은 일절 언급하지 않습니다.이것도 이 언어의 매력적인 점이라고 볼 수 있죠 😄언어의 주요 특징으로는 거의 모든 코드가 문자라는 것입니다.Rockstar의 주요 문법은 Hello World 코드 샘플을 분석해보며 훑어보겠습니다.해당 Rockstar 코드를 실행하면 콘솔 창에 Hello World가 출력됩니다. 엄청 길지만 참 멋진 코드입니다.Rockstar에서는 주석을 소괄호로 처리합니다.이번 게시글에서는 가볍게 알아보는 자리이므로 예제에 주석으로 코드가 의미하는 바를 분석해놓았고, 예제 밑에 주요 문법 특징을 적어보았습니다.• None Rockstar만의 독특한 언어 기능.• None 개발자 내면 깊숙한 곳의 공포, 두려움을 표현하도록 도와줍니다.• None• None 변수 이름 + 키워드 is, are, was, were 뒤에 오는 해당 줄의 코드는 모두 10진수로 취급됩니다.• None 따라서 The prize == 7이 됩니다.• None Rockstar에서 문자와 숫자는 유니코드를 기준으로 변환됩니다.• None with 뒤에 있는 원소를 삽입• None 변수 이름은 case insensitive이기 때문에 The dawn과 the dawn은 모두 같은 변수입니다.Rockstar 깃헙 레포지토리에 있는 예제를 이용해 "Hello World"를 출력해보았습니다.단순히 문자열만 출력하는 방법도 있지만 Rockstar 언어의 특징을 살려 "Hello World"를 출력한 코드를 보는 것이 더 의미있을 것 같아서 가져왔습니다.가끔 공부를 하다 보면, 이런저런 것들을 따지느라 프로그래밍 언어 자체의 매력을 잊어버릴 때가 있습니다.저는 그럴 때마다 재미난 것들을 탐구하며 시간을 보내곤 합니다. 이번 탐구 활동의 결과물인 프로그래밍 언어 Rockstar를 소개글을 작성해보았습니다.거의 처음 작성해보는 게시글이라 글의 전개나 글이 어색한 면이 없지 않아 있지만, 제가 해당 언어를 보고 느꼈던 즐거움이 전해졌으면 좋겠습니다.최근에는 상대적으로 친숙한 언어인 Java로 Rockstar 컴파일러를 조금씩 제작하고 있는데, 생각보다 쉽지 않네요 🥲모두 힘들더라도 🤘Rock n' Roll 🤘하며 이겨냅시다. 화이팅 !!앞서 언급한 The Art of Code 컨퍼런스 번역본에 관심 있으신 분 계신가요?
2024.04.30
emoji
좋아요
emoji
별로에요
logo
AI와 엣지 컴퓨팅의 결합
AI가 알파고에서 챗GPT로 초 거대화되고 클라우드의 성능이 더욱 좋아지면서, 엣지 컴퓨팅은 새로운 전환의 계기가 만들어지고 있습니다. 새로운 정보 단말기에는 AI가 기본으로 탑재될 것이고, AI를 품은 엣지 컴퓨팅은 더 많은 기기에 필수 기술로 자리 잡을 것으로 전망합니다.
4/30/2024
logo
AI와 엣지 컴퓨팅의 결합
AI가 알파고에서 챗GPT로 초 거대화되고 클라우드의 성능이 더욱 좋아지면서, 엣지 컴퓨팅은 새로운 전환의 계기가 만들어지고 있습니다. 새로운 정보 단말기에는 AI가 기본으로 탑재될 것이고, AI를 품은 엣지 컴퓨팅은 더 많은 기기에 필수 기술로 자리 잡을 것으로 전망합니다.
2024.04.30
emoji
좋아요
emoji
별로에요
logo
JPA에서 아이디를 자동증가 값으로 사용 시 하이버네이트의 @NaturalId 사용해 보기
JPA에서 아이디를 자동증가 값으로 사용 시 하이버네이트의 @NaturalId 사용해 보기신규 테이블 생성 시 기본키 생성은 어떻게 하고 계시나요? 저희팀에서는 기본 RDBMS 로 MySQL을 사용하고 있습니다.MySQL의 경우 기본키를 Clustered Index 로 사용하고 있습니다. Clustered Index란 데이터베이스 테이블에서 데이터를 저장하는 물리적인 순서를 인덱스 순서로 사용하는 것을 말합니다. 그래서 데이터 삽입 시 기본키 기준으로 데이터가 정렬되기 때문에 자동증가값 사용 시 삽입 성능이 좋습니다. 그리고 배치와 같이 대량의 데이터를 청크 단위로 조회할 때 offset-limit 쿼리로 조회했을 때보다는 아래처럼 기본키를 기준으로 조회했을 때 훨씬 빠르게 조회할 수 있습니다. 이러한 이유로 주로 기본키에는 auto_increment를 사용해 왔습니다.운영환경과 테스트환경의 아이디값 불일치로 인한 문제저희팀에서는 테스트환경과 운영환경을 함께 운영하고 있는데요, 테스트 환경의 경우에는 테스트용도로 데이터를 생성하다보니 운영환경과는 다른 데이터를 종종 생성하고는 합니다.그래서 자동증가 값을 기본키로 사용하는 엔티티 대부분이 운영환경과 테스트환경의 아이디값이 다르게 되어 있습니다.운영환경과 테스트환경의 아이디값이 달라서 문제가 됐던 경험이 있지 않으신가요?운영환경과 테스트환경의 아이디값 불일치 문제를 설명해보기 위해 특정한 요구사항이 들어온 상황을 가정해 보겠습니다.특정 상품의 판매 촉진을 위해 특정한 기간동안 특정 상품 몇개에 대해서만 80% 할인을 해야 한다는 요구사항이 들어왔습니다.현재 상품 테이블 구조는 아래와 같습니다.엔티티는 다음과 같습니다.현재는 할인 기능이 없습니다. 개발기간이 충분하다면 할인 기능을 개발하여 적용하고 싶지만, 안타깝게도 내일 모레부터 바로 운영환경에 적용되어야 하는 상황입니다.운영 배포전 테스트도 필요하기 때문에 내일 오전까지 개발완료 후 내일 오후부터는 테스트환경에 배포하여 테스트 이후에 모레 오전에 운영환경에 배포하기로 하였습니다.운영환경과 테스트환경의 상품이 모두 동일하면 좋았겠지만, 아쉽게도 테스트환경에는 테스트용으로 생성했던 상품들이 따로 존재합니다. 따라서 아래와 같이 동일한 상품이라도 아이디가 각각 다르게 등록되어 있습니다.하루 만에 모든 기능 개발을 끝마쳐야 하기 때문에 일단은 할인대상 상품 아이디 목록을 하드코딩하기로 하였습니다. 상품 아이디가 운영환경과 테스트환경에 각각 다르게 생성되어 있어서, 해당하는 상품들의 아이디를 운영환경과 베타환경에서 각각 찾아서 아래와 같이 사용하는 형태로 일단락지었습니다.열심히 개발하여 테스트환경에 배포하려는 순간 추가 요구사항이 발생하였습니다. 운영배포일 오전에 운영환경에 XXX와 YYY라는 상품이 신규로 생성되게 되는데, 신규로 생성되는 2개의 상품중 XXX 상품에도 동일하게 할인을 적용해 달라는 요구사항이였습니다.베타환경의 경우 새로운 상품을 추가 후 바로 해당 상품의 아이디를 yml 파일에 추가하였지만, 운영환경은 내일 상품이 새로 생성 되어야만 아이디 값을 알 수 있어서 운영환경에 추가된 상품의 아이디 값을 어떻게 yml 파일에 추가할지 고민이 생겼습니다.먼저 떠오른 생각은 상품을 먼저 생성 후 생성된 상품의 아이디를 확인 후 코드상에 추가한 뒤 배포하는 방법이었습니다.하지만 배포를 위해 아침 일찍 일어나 코딩까지 하기에는 너무나 억울한 마음이 들었던 저는 아이디 값이 어차피 자동증가 값이니 현재까지의 상품등록 추이를 보았을 때 알파벳순으로 상품이 등록되었으니 이번에도 XXX, YYY순으로 상품이 등록될 것으로 예상하여 현재 운영환경에 등록된 가장 큰 아이디값에 +1만 해주면 될 것이라는 생각을 하게 되었습니다.그래서 현재 운영환경에 등록된 상품 중 가장 큰 아이디값인 5에다가 +1 해준 값인 6을 아래처럼 yml 파일에 추가하였고 운영환경에 그대로 배포하였습니다.오전에 운영환경에 배포 이후 즐겁게 일하고 있던 저에게 갑자기 문의가 들어왔습니다.오늘 운영환경에 추가한 상품 중 XXX 상품이 할인되어야 하지만, 실제로는 YYY 상품이 할인되고 있다는 문의였습니다.원인은 상품의 순서가 예상과는 달리 XXX, YYY 순서로 등록되지 않고 반대 순서인 YYY, XXX 순서로 상품이 등록되는 바람에 YYY 상품이 할인되고 있었습니다.급하게 운영환경에 하드코딩된 아이디 값을 고쳐서 재배포 이후에는 정상적으로 XXX 상품이 할인될 수 있었습니다.변경되지 않는 유니크 키가 설정된 컬럼을 사용해 보자위의 사례와 같이 운영환경과 테스트환경의 자동증가하는 아이디값이 불일치하여 발생하는 일을 방지하기 위해서는 어떻게 해야 할까요?여러 가지 방법이 있겠지만 한 가지 방법으로는 아래와 같이 자동 증가하는 아이디값 외에 유니크 키가 적용된 컬럼을 하나 더 추가하여 코드에서 자동증가값 대신에 유니크 키 컬럼을 사용해 보는 방법이 있습니다.컬럼의 경우 아이디 값 대신에 사용되어야 합니다. 즉 생성만 가능하고 변경이 되면 안 됩니다. 이에 아래와 같이 생성자에서만 전달받도록 엔티티를 수정하였습니다.추가된 유니크키 컬럼값을 통해 운영환경과 테스트환경에서 동일한 식별값으로 데이터를 생성할 수 있게 되어 아이디가 불일치하여 생기는 문제는 예방할 수 있게 되었습니다.그래서 이제부터는 아이디 대신 유니크키 컬럼 값으로 조회하여 사용하기로 마음먹고 아래와 같이 메서드를 에 추가 후 기존 메서드를 사용하는 부분들을 모두 메서드를 사용하도록 수정하기로 하였습니다.사용시 모든 기능은 정상동작하지만, 한 가지 마음에 걸리는 게 생겼습니다.동일한 트랜잭션에서 동일한 엔티티를 여러 번 조회하는 경우, 를 사용하면 한 번만 쿼리가 발생하지만 를 호출하면 매번 쿼리가 발생한다는 점입니다. ProductRepositoryTest.java[참고] MySQL 이나 MariaDB 드라이버를 사용하는 경우 아래와 같은 설정으로 쿼리 로그를 남길 수 있습니다.하이버네이트의 @NaturalId를 사용해 보자찜찜함을 해결하기 위해 열심히 이곳저곳을 찾아보다가 하이버네이트에는 가 붙은 필드가 아닌 필드에 선언하여, 가 붙은 필드와 유사하게
java
4/30/2024
logo
JPA에서 아이디를 자동증가 값으로 사용 시 하이버네이트의 @NaturalId 사용해 보기
JPA에서 아이디를 자동증가 값으로 사용 시 하이버네이트의 @NaturalId 사용해 보기신규 테이블 생성 시 기본키 생성은 어떻게 하고 계시나요? 저희팀에서는 기본 RDBMS 로 MySQL을 사용하고 있습니다.MySQL의 경우 기본키를 Clustered Index 로 사용하고 있습니다. Clustered Index란 데이터베이스 테이블에서 데이터를 저장하는 물리적인 순서를 인덱스 순서로 사용하는 것을 말합니다. 그래서 데이터 삽입 시 기본키 기준으로 데이터가 정렬되기 때문에 자동증가값 사용 시 삽입 성능이 좋습니다. 그리고 배치와 같이 대량의 데이터를 청크 단위로 조회할 때 offset-limit 쿼리로 조회했을 때보다는 아래처럼 기본키를 기준으로 조회했을 때 훨씬 빠르게 조회할 수 있습니다. 이러한 이유로 주로 기본키에는 auto_increment를 사용해 왔습니다.운영환경과 테스트환경의 아이디값 불일치로 인한 문제저희팀에서는 테스트환경과 운영환경을 함께 운영하고 있는데요, 테스트 환경의 경우에는 테스트용도로 데이터를 생성하다보니 운영환경과는 다른 데이터를 종종 생성하고는 합니다.그래서 자동증가 값을 기본키로 사용하는 엔티티 대부분이 운영환경과 테스트환경의 아이디값이 다르게 되어 있습니다.운영환경과 테스트환경의 아이디값이 달라서 문제가 됐던 경험이 있지 않으신가요?운영환경과 테스트환경의 아이디값 불일치 문제를 설명해보기 위해 특정한 요구사항이 들어온 상황을 가정해 보겠습니다.특정 상품의 판매 촉진을 위해 특정한 기간동안 특정 상품 몇개에 대해서만 80% 할인을 해야 한다는 요구사항이 들어왔습니다.현재 상품 테이블 구조는 아래와 같습니다.엔티티는 다음과 같습니다.현재는 할인 기능이 없습니다. 개발기간이 충분하다면 할인 기능을 개발하여 적용하고 싶지만, 안타깝게도 내일 모레부터 바로 운영환경에 적용되어야 하는 상황입니다.운영 배포전 테스트도 필요하기 때문에 내일 오전까지 개발완료 후 내일 오후부터는 테스트환경에 배포하여 테스트 이후에 모레 오전에 운영환경에 배포하기로 하였습니다.운영환경과 테스트환경의 상품이 모두 동일하면 좋았겠지만, 아쉽게도 테스트환경에는 테스트용으로 생성했던 상품들이 따로 존재합니다. 따라서 아래와 같이 동일한 상품이라도 아이디가 각각 다르게 등록되어 있습니다.하루 만에 모든 기능 개발을 끝마쳐야 하기 때문에 일단은 할인대상 상품 아이디 목록을 하드코딩하기로 하였습니다. 상품 아이디가 운영환경과 테스트환경에 각각 다르게 생성되어 있어서, 해당하는 상품들의 아이디를 운영환경과 베타환경에서 각각 찾아서 아래와 같이 사용하는 형태로 일단락지었습니다.열심히 개발하여 테스트환경에 배포하려는 순간 추가 요구사항이 발생하였습니다. 운영배포일 오전에 운영환경에 XXX와 YYY라는 상품이 신규로 생성되게 되는데, 신규로 생성되는 2개의 상품중 XXX 상품에도 동일하게 할인을 적용해 달라는 요구사항이였습니다.베타환경의 경우 새로운 상품을 추가 후 바로 해당 상품의 아이디를 yml 파일에 추가하였지만, 운영환경은 내일 상품이 새로 생성 되어야만 아이디 값을 알 수 있어서 운영환경에 추가된 상품의 아이디 값을 어떻게 yml 파일에 추가할지 고민이 생겼습니다.먼저 떠오른 생각은 상품을 먼저 생성 후 생성된 상품의 아이디를 확인 후 코드상에 추가한 뒤 배포하는 방법이었습니다.하지만 배포를 위해 아침 일찍 일어나 코딩까지 하기에는 너무나 억울한 마음이 들었던 저는 아이디 값이 어차피 자동증가 값이니 현재까지의 상품등록 추이를 보았을 때 알파벳순으로 상품이 등록되었으니 이번에도 XXX, YYY순으로 상품이 등록될 것으로 예상하여 현재 운영환경에 등록된 가장 큰 아이디값에 +1만 해주면 될 것이라는 생각을 하게 되었습니다.그래서 현재 운영환경에 등록된 상품 중 가장 큰 아이디값인 5에다가 +1 해준 값인 6을 아래처럼 yml 파일에 추가하였고 운영환경에 그대로 배포하였습니다.오전에 운영환경에 배포 이후 즐겁게 일하고 있던 저에게 갑자기 문의가 들어왔습니다.오늘 운영환경에 추가한 상품 중 XXX 상품이 할인되어야 하지만, 실제로는 YYY 상품이 할인되고 있다는 문의였습니다.원인은 상품의 순서가 예상과는 달리 XXX, YYY 순서로 등록되지 않고 반대 순서인 YYY, XXX 순서로 상품이 등록되는 바람에 YYY 상품이 할인되고 있었습니다.급하게 운영환경에 하드코딩된 아이디 값을 고쳐서 재배포 이후에는 정상적으로 XXX 상품이 할인될 수 있었습니다.변경되지 않는 유니크 키가 설정된 컬럼을 사용해 보자위의 사례와 같이 운영환경과 테스트환경의 자동증가하는 아이디값이 불일치하여 발생하는 일을 방지하기 위해서는 어떻게 해야 할까요?여러 가지 방법이 있겠지만 한 가지 방법으로는 아래와 같이 자동 증가하는 아이디값 외에 유니크 키가 적용된 컬럼을 하나 더 추가하여 코드에서 자동증가값 대신에 유니크 키 컬럼을 사용해 보는 방법이 있습니다.컬럼의 경우 아이디 값 대신에 사용되어야 합니다. 즉 생성만 가능하고 변경이 되면 안 됩니다. 이에 아래와 같이 생성자에서만 전달받도록 엔티티를 수정하였습니다.추가된 유니크키 컬럼값을 통해 운영환경과 테스트환경에서 동일한 식별값으로 데이터를 생성할 수 있게 되어 아이디가 불일치하여 생기는 문제는 예방할 수 있게 되었습니다.그래서 이제부터는 아이디 대신 유니크키 컬럼 값으로 조회하여 사용하기로 마음먹고 아래와 같이 메서드를 에 추가 후 기존 메서드를 사용하는 부분들을 모두 메서드를 사용하도록 수정하기로 하였습니다.사용시 모든 기능은 정상동작하지만, 한 가지 마음에 걸리는 게 생겼습니다.동일한 트랜잭션에서 동일한 엔티티를 여러 번 조회하는 경우, 를 사용하면 한 번만 쿼리가 발생하지만 를 호출하면 매번 쿼리가 발생한다는 점입니다. ProductRepositoryTest.java[참고] MySQL 이나 MariaDB 드라이버를 사용하는 경우 아래와 같은 설정으로 쿼리 로그를 남길 수 있습니다.하이버네이트의 @NaturalId를 사용해 보자찜찜함을 해결하기 위해 열심히 이곳저곳을 찾아보다가 하이버네이트에는 가 붙은 필드가 아닌 필드에 선언하여, 가 붙은 필드와 유사하게
2024.04.30
java
emoji
좋아요
emoji
별로에요
logo
고객 구매 경험의 진화 방향 - 자동차 구매 경험을 중심으로
디지털 고객 경험을 통해 상품을 구매하고 서비스를 상호작용하는 방식이 변화하고 있습니다. 자동차 판매업체는 소비재 판매업체로부터 변화를 수용하고 진화하는 방법을 배울 수 있습니다.
4/30/2024
logo
고객 구매 경험의 진화 방향 - 자동차 구매 경험을 중심으로
디지털 고객 경험을 통해 상품을 구매하고 서비스를 상호작용하는 방식이 변화하고 있습니다. 자동차 판매업체는 소비재 판매업체로부터 변화를 수용하고 진화하는 방법을 배울 수 있습니다.
2024.04.30
emoji
좋아요
emoji
별로에요
Copyright © 2024. Codenary All Rights Reserved.