23.06.15
DEVOTEE를 활성화 시키면
지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.
버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.
| 컨텐츠 유형 | 제목 | 저장일 | 삭제 |
|---|
본인인증 로그인에 실패하였습니다.
회원이 아니시거나 본인인증 등록이
완료되지 않은 사용자입니다.
안녕하세요! Tech 시장에 큰 파도를 일으킬 DEVOCEAN YOUNG 3기 TechWave 팀입니다. 🌊
미션 하나로 시작되는 가족의 대화와 추억, 설렘 “올랑올랑”의 개발 프로젝트 진행기를 소개드립니다!
올랑올랑의 시작은 가족을 위한 앱이 아닌, 시니어를 위한 앱이었다는 거 아셨나요?
빠른 고령화 사회 진입, 독거노인의 증가, 가족 간 의사소통의 부재 등 고령화사회로 인해 발생하는 문제들에 주목해보고,
시니어와 자녀들을 미션으로 이어주는 앱으로 시작했어요. 기능은 아래와 같았어요!
자식 세대가 미션 제공 → 부모 세대는 특정 기간 내에 미션 수행 (ex. 꽃에 물 주기 / 일주일에 한 번)
세대 맞춤 UI로 시니어는 버튼 하나만 터치하면 수행 인증 끝!
하지만, 시니어만으로 타겟팅하는 건 문제가 있었는데요.
< 기획 발표 > 하늬님의 피드백
- 저출산 시대에 자녀가 없는 경우가 많은데 이때는 어떻게 해결할 수 있을까요?
- 이러한 경우에 1인 가구끼리 연결할 수 있는 기능도 있으면 좋을 것 같아요기획 발표에서 얻은 기획 관련 피드백으로 워크샵까지 새로운 타겟팅으로 피봇팅하고 개발하는 시간을 가졌습니다.
(왼쪽) 초기버전 (오른쪽) ver.0 (피봇팅1)
처음에는 왼쪽에 보이는 것처럼 시니어 타겟이었지만, 오른쪽에 보이듯 타겟을 ‘가족과 지인’으로 변경했습니다.
저희가 풀어주고 싶은 문제는 소통이었기 때문에 저출산 시대와 1인 가구 증가에 집중했고, 타겟팅을 조금 바꿔보았습니다.
그래서 아래와 같은 기능들을 만들어서 데보션 영 워크샵(중간 발표) 때 발표했습니다.
미션 목록으로 진행중인 미션 개수 가시화
미션 수행 도장판과 가족, 지인의 응원이 담긴 미션
맞춤형 미션 보내기
간편한 미션 달성 인증
나와 연결고리가 있는 올랑이들(가족/지인) 추가
워크샵 때 첫 번째로 발표한 만큼 정말 다양한 피드백을 받을 수 있었는데요!
< 중간 발표 > 프로님들의 피드백
- 미션이라는 관점에서 의무적인 내용이 많은 것 같아서 게임 등 흥미를 유발하여 자연스러운 동기를 부여할 수 있는 부분 고려하는 것이 좋겠다.
- 보통 사진을 통해 대화하고 과거 사진을 통해 대화한다. 사진에 관련된 기능 추가하면 소통할 거리 많아질 듯하다.
- 미션의 의미 부각이 필요할 것 같다. (미션의 카테고리화)
- AI가 현재 기획한 가족에게 대신 말을 써주는 LLM이 아니라, AI로 수행한 미션 한 줄 요약, 미션 이름을 감성적으로 만들어주는 기능 등이 있으면 좋겠다.위와 같은 피드백을 받고 기획을 조금 더 세밀하게, 그리고 개발도 꼭 필요한 기능을 덧붙여보기로 생각했습니다.
정말 저희와 같은 팀원인 것처럼 좋은 피드백을 많이 주셔서 저희도 생각하지 못한 부분을 수정할 수 있었습니다.
(기존) 가족이 서로 미션을 주는 형태 -> (신규) 가족 모두가 한 팀으로 하나의 미션을 공동 수행
(기존) 미션 인증 시 넣은 사진이 추억이 될 것 같은데 아무 곳에도 쓰이지 않음 -> (신규) 가족 앨범 만들어주기
(기존) 가족에게 대신 따뜻한 말을 만들어주는 LLM -> (신규) 가족 미션 인증 사진에 여행간 듯 배경을 만들어주는 생성형 AI
위 수정사항을 기반으로 아래의 기능들이 만들어집니다!
[ 사용자 앱 이용 플로우 ]
오늘의 미션 카테고리에서 4개 중 하나를 골라 가족과 미션을 수행한다. (카테고리 : 일상, 운동, 감사, 여행)
미션 인증하기 버튼을 눌러 가족과 함께 미션을 수행한 사진을 첨부한다.
원하는 배경 테마를 선택한다. (테마 : 크리스마스, 가을 낙엽, 해외여행, 꽃밭 등)
올랑올랑 AI가 생성형 AI로 배경을 만들어준다.
쌓인 미션 기록은 가족 공유 앨범을 통해 볼 수 있다.
미션 인증 개수로 포인트 점수화한 올랑올랑 가족 랭킹을 볼 수 있다.
가족, 지인에서 타겟도 '가족'으로 줄이고 저희가 추가로 만드려고 했던 AI 기능도 가족에게 집중해서 새로 기획 후 만들어보았습니다. (ver.0과 완전히 다른 모습이죠?)
피봇팅이 기획 관점에서는 많이 바뀌지 않은 것 같지만, 개발을 할 때는 화면이 모두 바뀌는 일이 생겨서 개발자인 팀원 5명 모두 조금씩 힘들었던 것 같은데요. 😅
그렇지만 사용자를 생각하며 기획도, 개발도 수정해본 경험이 재밌었던 것 같기도 합니다.
최종 발표 때 발표 시간을 맞추기 위해서 직접 시연이 아닌 영상으로 준비했는데요!
아래 링크에서 보실 수 있으니 참고 부탁드립니다! 😊
TechWave Github : https://github.com/Devocean-TechWave
OLOL-AI : AI 개발 레포지토리
OLOL-backend : 백엔드 개발 레포지토리
OLOL-android : 안드로이드 개발 레포지토리
OLOL-Landing : 워크샵 시연 때 사용한 랜딩페이지 레포지토리
1️⃣ ver.0에서는, 6개월 잡고 Jetpack 도전!
팀원 장세연, 피유진이 같은 도서 ‘Android Jetpack’ 스터디를 하고 있었기에 Jetpack을 사용해서 개발해봐야겠다고 생각했는데요!
항상 xml로 UI를 개발해오던 Android 개발자 두 명에게 선언형인 Jetpack이 큰 도전이었습니다. 그래서 시간이 많이 걸리기도 했는데요. 🥲
워크샵까지 개발을 완료하고자 하단 탭은 Jetpack, 화면이 나올 UI는 xml로 제작해보기도 했는데 Jetpack으로 그린 화면과 xml로 그린 화면을 잇는 작업에서도 많은 시간이 소요됐습니다.
그래서 백엔드 개발은 완료됐었지만, 모바일 개발은 50% 정도 완료한 상태로 중간 발표를 진행했습니다.
2️⃣ ver.1에서는, 구현을 목표로!
ver.0에서 ver.1로 넘어가면서 완전히 새로운 UI와 디자인을 적용해야 했기 때문에, 사실상 처음부터 다시 시작하는 것과 같았습니다.
따라서, 하나의 프로젝트를 새로 만드는 것이다 보니 빠른 개발이 우선이겠다고 생각해서 Jetpack 보다는 먼저 xml로 만들고, 추후 Jetpack으로 리팩토링을 하기로 결정했습니다.
이로 인해 개발 속도를 높일 수 있었지만, 새로운 UI와 기능을 적용하면서 발생하는 디테일한 문제들을 해결하는 데 많은 시간이 걸렸습니다. 😅
그럼에도 아래와 같은 개발적 요소를 고민하고 적용해보았습니다.
MVVM 패턴을 항상 사용하고는 있었지만, 폴더 분류를 정확히 하기 위해 문서도, 여러 블로그도, Github도 정말 열심히 찾아본 것 같습니다.
그 결과 위와 같이 분류를 해보았는데요. 이유는 다음과 같습니다.
Data, Domain, Presentation으로 분리한 이유는 클린 아키텍처를 기반으로 코드 의존성과 책임을 분리하기 위해서 인데요.
data 는 외부 데이터(서버)와의 상호작용을, domain 은 핵심 비즈니스 로직을, presentation 은 사용자 인터페이스와 화면 동작을 담당하도록 설계했습니다.
각 레이어 안에서도 역할과 책임을 더 명확히 하기 위해 세부 폴더를 구분했습니다.
예를 들어, data에서는 데이터 관련 작업을 담당하는 api, 데이터 변환을 처리하는 dto, 데이터 소스를 관리하는 repository, 로직 구현을 위한 service를 분리해 책임을 나눴습니다.
또한, 앨범이나 랭킹 화면처럼 넘어올 데이터가 무수히 많아지는 화면에서는 Pagination을 적용했습니다.
방대한 이미지를 가져올 때 좋은 사용자 경험을 위해서는 스크롤 성능 최적화가 필요할 것이라 생각하여, 페이지네이션은 ViewModel의 Pager로 관리하고, Flowable 형태로 UI에 데이터를 전달했습니다.
이를 통해 데이터 흐름이 분리되어 클린 아키텍처를 유지하면서도 비동기 처리로 성능을 최적화할 수 있었습니다. UI에서는 PagingDataAdapter를 통해 데이터를 효율적으로 로드할 수 있도록 개발했습니다.
1️⃣ ver.0 아키텍처
초기 데이터베이스는 유저를 중심으로 설계했습니다. 유저 관계 테이블을 통해 친구 관계(요청, 수락, 삭제)를 관리하고, 이는 Enum을 사용해 구체화했습니다.
또한, 미션 테이블과 성공 기록 테이블을 매핑해 유저의 미션 성공 기록을 관리하며, 응원 테이블을 통해 다양한 응원 메시지를 주고받을 수 있도록 설계했습니다.
2️⃣ ver.1 수정 아키텍처
전체적인 기획이 바뀌면서 데이터베이스 스키마에도 수정이 필요했습니다.
새로운 요구사항을 반영하기 위해 데이터베이스 설계를 조정하고 최적화하여 데이터의 정합성을 높일 수 있었습니다.
데이터베이스 역정규화를 통해 엔티티를 통합함으로서 조인 횟수를 줄이고 복잡한 쿼리를 줄일 수 있었습니다.
초기 시스템 아키텍처는 간단하게 EC2 인스턴스를 사용해 구축했으나, 테스트 중 성능 이슈가 발생했습니다.
이를 해결하기 위해 구조를 Application Load Balancer와 ECS를 사용하는 방식으로 변경했습니다.
CI/CD 파이프라인은 GitHub Actions와 CodePipeline을 통해 자동화하였으며, 컨테이너 이미지는 ECR에 빌드 및 푸시한 후, Fargate에서 서버리스 환경으로 실행 및 관리하고 있습니다.
현재는 모니터링을 위해 Datadog Agent를 컨테이너 형식으로 함께 띄워 실시간 매트릭을 확인할 수 있습니다.
또한, 중간발표 이후 JPQL 사용이 많다는 부분과 ‘사진을 어떻게 효과적으로 저장할 것인지'에 대한 피드백, 패키지 별 도메인 분리와 관련하여 피드백을 받았고 이를 기반으로 수정을 진행할 수 있었습니다.
✅ 중간발표 피드백 반영 수정사항 ✅
JPQL에서 QueryDSL로 전환
중간발표 당시, 기존 깃허브 코드를 보고 한 프로님께서 jpql사용이 많다고 피드백을 주셨습니다.
JPQL을 사용해 오던 쿼리 방식을 QueryDSL로 전환하여 코드의 가독성과 유지보수성을 높였습니다.
특히, 복잡한 동적 쿼리를 보다 유연하게 작성할 수 있어 개발 속도와 효율이 향상되었습니다.
사진 저장 및 관리 전략
AWS S3를 활용하여 앨범을 저장하며, 오래된 앨범은 S3 수명 주기를 통해 자동으로 관리하도록 설계했습니다.
생성 후 30일이 지나면 객체를 S3 Standard-IA (Infrequent Access)스토리지 클래스로 전환되고, 생성 후 1년이 지나면 객체를 S3 Glacier 스토리지 클래스에 아카이브됩니다.
이러한 비용 절감 전략을 통해 사용하지 않는 데이터를 효율적으로 정리함으로써 저장 공간과 비용을 절감할 수 있었습니다.
이미지 리사이징 기능 개선
S3 Object Lambda를 적용하여 On-Demand 이미지 리사이징 방식을 구현하여, 사용자가 요청한 크기로 이미지를 동적으로 리사이징하였습니다.
리사이징된 이미지는 CDN에 캐싱되어 같은 요청이 반복될 때 빠르게 제공될 수 있습니다.
이를 통해 이미지를 그대로 저장하던 기존 방식보다 효율적이고 빠르며, 저장 공간을 절약할 수 있었습니다.
도메인 기반 패키지 분리 + 예외처리 문서화
기존의 예외 처리 클래스 등의 경계가 모호했던 구조에서 도메인 중심으로 패키지를 분리하여 각 기능이 보다 명확하게 구분되도록 했습니다.
기능별 책임이 명확해져 유지보수와 확장성 측면에서 효율성을 높일 수 있었습니다.
이를 통해 각 도메인이 독립적으로 관리되면서도 전체 시스템의 일관성을 유지할 수 있었습니다.
또한, 각 도메인별로 발생할 수 있는 예외를 정의하고 이를 Swagger를 통해 문서화했습니다.
API를 사용하는 개발자들이 예외 상황을 사전에 파악할 수 있도록 하여 개발 측면에서 협업의 편의성을 높였습니다.
AI 기능은 크게 가족 미션 추천과 가족사진 배경 생성 두 가지 부분에 적용했습니다.
가족 미션 추천은 GPT API를 활용하여 구현하였으며, 미션 유형을 일상, 운동, 감사, 여행의 네 가지로 나누어 사용자 입력을 기반으로 유형에 맞는 질문을 추천하는 방식입니다.
이를 위해 프롬프트를 구체화하여 작성함으로써 보다 적합한 미션 추천이 가능해졌고, 이를 통해 사용자 편의성을 크게 높일 수 있었습니다.
유형을 구체화함으로써 가족 중 한 명이 몸이 좋지 않아 활동적인 미션이 어려운 상황에 운동 관련 미션이 추천되는 문제를 방지할 수 있게 되었습니다.
생성형 AI를 구현하는 과정에서 많은 시행착오를 겪었습니다. 초기에는 보유 중인 코랩 프로 플러스 계정을 활용하면 학습이 가능할 것이라 판단하고 직접 모델 학습을 시도하였습니다.
모델 설계 과정에서는 기존 오픈소스 모델을 참고하되 논문 연구 내용을 적용해 커스터마이징을 시도했습니다.
Conv2D 레이어 대신 Weight Standardized Conv2D 레이어를 도입하였습니다.
이 기법은 가중치 표준화를 통해 Group Normalization과의 시너지를 기대할 수 있으며, 일부 연구에서 성능 향상이 보고된 바 있습니다.
또한, MHSA 외에도 메모리 사용량을 줄이기 위해 Linear Attention을 별도로 구현하였습니다.
모델의 구조는 U-Net 기반으로 설계했으며, Residual 블록, PreNorm, Linear Attention, Weight Standardized Conv2D 레이어를 조합해 더욱 깊고 복잡한 네트워크를 구성하였습니다.
이를 통해 다양한 해상도와 복잡한 장면을 안정적으로 생성할 수 있도록 설계해보았습니다.
데이터셋은 캐글허브에서 제공하는 사람이 없는 자연 및 도시 풍경 이미지로 라벨 필터링을 진행했습니다.
필터링된 약 2,250개의 이미지를 150 에포크로 학습을 시도했으나, GPU 자원의 한계로 인해 학습이 중단되었습니다.
이에 이미지 수를 1,000개로 제한하고 약 13시간 동안 학습을 진행했지만, 모델이 반환한 결과는 거의 노이즈에 가까웠습니다.
이후에 현직자분께 일반적인 GPU 자원으로는 생성형 AI 모델을 효과적으로 학습하기 어렵다는 조언을 받았고, 기존 오픈소스 모델을 사용하는 방향으로 전환하게 되었습니다.
오픈소스 모델을 그대로 사용할 경우 프롬프트 엔지니어링으로 부정 조건을 추가하더라도 사람이 포함된 이미지가 생성되는 문제가 발생했습니다.
이를 해결하기 위해, 500개의 자연 풍경 이미지를 BLIP 캡션과 매칭한 데이터셋을 구성하고, 이를 기반으로 LoRA 기법을 활용해 모델 최적화를 진행했습니다.
LoRA를 도입함으로써 GPU 메모리와 연산량을 크게 절약할 수 있었고, 적은 양의 이미지 데이터로도 효율적인 학습이 가능했습니다.
이를 통해 사람이 포함되지 않은 자연 및 도시 배경 이미지를 안정적으로 생성하는 AI 모델을 구현할 수 있었으며,
최종적으로 모델은 Flask를 통해 배포하고 JPA와 연결하여 프로젝트에 통합했습니다.
TechWave는 총 5명의 팀원으로 구성되어 있습니다.
Android 개발을 담당하는 2명의 개발자 장세연, 피유진
SpringBoot 백엔드 개발을 담당하는 2명의 개발자 김유빈, 신중은
AI 개발을 담당하는 염정
저희는 처음부터 정말 세상에 필요한 서비스, 세상에 빛과 소금이 될 서비스가 무엇인지 고민을 많이 했습니다.
그래서 고객의 페인포인트를 찾을 때 통계나 기사도 많이 검색해보고, 서비스가 정말로 도움이 될 지에 대한 고민을 많이 해서 기획도 니즈에 맞도록 수정했던 것 같은데요!
원래 저희 팀의 목표는 사용자를 모아보는 것이였는데, 2번의 피봇팅으로 목표를 이루진 못 했으나
피드백에서 타겟팅과 기획이 좋다는 피드백도 받고, 개발을 완성하고 최종발표에 참여할 수 있었다는 점이 제일 뿌듯했습니다. 😊
🌊 김유빈
안녕하세요! Techwave 팀에서 올랑올랑의 백엔드를 맡은 김유빈입니다.
데보션영의 핵심 활동인 개발 과제를 진행하며, 팀원들과의 협업을 통해 함께 개발하는 것의 가치를 다시 한번 깊이 느낄 수 있었습니다.
특히, 백엔드와 프론트엔드 모두 열정적으로 참여한 덕분에 최고의 결과를 만들어낼 수 있었던 것 같습니다.
워크숍에서도 현직자분들의 조언을 들으며 프로젝트를 더 완성도 있게 다듬을 수 있어 정말 뜻깊고 즐거운 경험이었습니다! 감사합니다.
🌊 신중은
안녕하세요! Techwave 팀에서 올랑올랑의 백엔드를 맡은 신중은입니다.
데보션영 활동 중 가장 오랜 시간을 투자하며 가장 기억에 남는 경험을 꼽으라면 단연 개발 과제일 것 같습니다.
팀원들에게 배울 점이 정말 많았고, 모두 바쁜 와중에도 함께 프로젝트를 진행할 수 있었던 점이 매우 뜻깊었습니다.
비대면으로도 효율적으로 시간을 활용하며 협업했기에, 짧은 시간 안에 빠르게 개발을 완료할 수 있었습니다.
또한, 현직자분들께 직접 발표하고 피드백을 받을 수 있었던 소중한 기회가 정말 값졌습니다. 좋은 경험이었습니다!
🌊 장세연
안녕하세요, TechWave 팀명을 지은 팀장 장세연입니다. :D
프로젝트 기획과 개발 경험은 많았지만, 현직자분들께 피드백을 직접 받아본 건 이번이 처음이었습니다.
세심한 피드백을 통해 많은 것을 배울 수 있었고, 정말 감사했습니다. 그 마음을 어떻게 전할까 고민하다가 글로나마 남겨봅니다. 다시 한번 감사드립니다!
팀원 중 세 명은 IT 동아리/그룹의 리더를 맡고 있고, 다른 두 명도 바쁜 일정 속에서 함께 했는데요.
그럼에도 불구하고 열심히 각자 맡은 일을 하고 좋게 마칠 수 있어서 모두에게 고맙다고 말하고 싶습니다. 😊
🌊 염정
안녕하세요! Techwave 팀에서 올랑올랑의 AI를 맡은 염정입니다.
저는 원래 AI 팀원이지만, 이번 프로젝트에서 백엔드 개발에도 도전해보고 싶다는 의사를 밝혔고, 팀원들의 배려 덕분에 백엔드 작업에도 함께 참여할 수 있었습니다.
특히, 뛰어난 백엔드 팀원들과 협업하면서 코드 리뷰를 통해 제 코드를 개선할 수 있었고, 아키텍처 설계 과정에서도 많은 것을 배우며 성장할 수 있었습니다.
데보션영을 통해 이렇게 다양한 경험을 쌓을 수 있었던 점이 정말 소중했고, 이를 통해 많은 배움을 얻었습니다.
함께 열심히 노력해준 팀원들에게 진심으로 고맙다는 말을 전하고 싶습니다!
🌊 피유진
안녕하세요! 이번에 안드로이드로 올랑올랑을 개발하게 된 피유진입니다.
팀원들과 함께 다양한 미션을 수행해 왔는데, 마지막으로 개발 미션까지 진행할 수 있어서 정말 뜻깊었습니다.
특히, 현직자분들로부터 직접 피드백을 받으며 서비스를 발전시켜 나갈 수 있었던 점이 매우 인상 깊었습니다.
각자의 전문 분야를 가진 팀원들과 협업하며 함께 개발을 진행한 덕분에 많은 것을 배우고 성장할 수 있었던 시간이었습니다. 감사합니다!
DEVOTEE를 활성화 시키면
지금 작성한 댓글에 AI가 댓글을 달아줍니다.