[OpenSource] OSSCA 기간 중 ORAN 프로젝트 기여 내용 총정리
카테고리:
tag #
2025년 11월 09일
// Links to the libraries needed
올해는 운 좋게도 7월 12일에서 10월 31일까지 진행하는 OpenSource Contribution Academy 참가형 프로그램의 O-RAN Software Community AI/ML Framework(AIMLFW) 프로젝트에 선발되어 참여하게 됐습니다.
이번 프로그램에서는 코드 기여 + 아키텍처 논의 + Gerrit 리뷰 플로우까지 전부 경험해볼 수 있었습니다.
이 글에서는 제가 AIMLFW에 기여하면서
를 정리해보려고 합니다.
처음에는 RAM 16G, Disk 512G의 M1 맥북을 가지고 프로젝트를 시작했습니다.
그런데 AIMLFW 쪽 배포 스크립트와 의존 구성 요소들이 amd64(x86_64) 전제로 구성된 부분이 많아서,
ARM 환경에서는 컨테이너 이미지/도구 몇 개가 제대로 동작하지 않아 환경 세팅이 제대로 되지 않는 이슈가 있었습니다.
또한 권장 사양도 RAM 32G부터인 문제도 있었습니다.
처음에는 이 부분을 기여 대상으로 삼아 “Mac 환경에서 제대로 구동되도록 해보자…!”라고 생각해보았지만 저 혼자 할 수 없을 것 같은 크기의 기여였고, 쿠버네티스/스토리지/모니터링까지 한 번에 돌려야 해서 리소스와 아키텍처 이슈가 생각보다 컸습니다.
그래서 결국 제가 생각한 가장 효율적인 방법은 다음과 같습니다.
맥은 개발용 클라이언트(IDE, 브라우저)로 쓰고,
실제 AIMLFW 클러스터는 집에 있는 윈도우 노트북에서 돌리자.
둘은 Tailscale로 하나의 네트워크처럼 묶자
제가 실제로 구축한 흐름은 대략 이런 느낌이었습니다.
docker, kind 또는 nerdctl 기반 컨테이너 환경 구성http://윈도우-Tailscale-IP:포트 형태로 접근이렇게 구성을 완료하였습니다!!
이제 본격적으로 제가 AIMLFW에 했던 기여들을 정리해보겠습니다.
여러 번의 nerdctl rmi 호출을 이미지 리스트 한 번 호출로 통합하여 스크립트를 단순화하는 데에 목적을 두었습니다!
해당 프로젝트의 첫 기여인만큼 최대한 간단한 기여를 하였는데요!
당시 스크립트는 이미지 ID 하나당 nerdctl rmi를 N번 호출하는 형태였고, 조금 더 단순하게 만들고 싶다는 생각이 들었습니다.
그래서 방향을 이렇게 잡았습니다.
이런 식으로 정리하면
다만 이 아이템은 코드 기여 후 디스코드에서 비슷한 이슈를 이미 선점한 멘티 분이 있다는 것을 확인했고,
중복 작업이 되지 않도록 자체적으로 기여를 Abandon(반려) 했습니다.
저희 멘티단의 목표 중 하나로 모델을 학습시켜주는 LLM Chatbot 제작이 있었고, 저희 과정에는 연구생 멘티 분들이 많았어서 멘토님이 실제 현업을 하고 있는 저에게 LLM Chatbot 구조 설계를 부탁하셨습니다!
우선 Notion에 제일 최소한의 단위의 문서를 만들었고 Flow Diagram도 간단하게 만들어두었습니다.
이후 회의에서 구조에 대한 발표를 하였고,

회의를 통해 초안을 확정하였습니다.
논의를 거치면서 구조가 어느 정도 합의되자, 이를 기반으로 공식 문서 공간인 Confluence에 정리했습니다.
여기에는 공식문서에 필요한 최소한의 내용만 정리하여 적어두었습니다.
이후 메인 컨테이너에게 API 엔드포인트의 최상위 루트 네임을 변경하는 등의 피드백을 받아 수정하였습니다.
이후 멘토, 멘티님들과의 논의를 통해 위 내용을 바탕으로 먼저 프론트엔드 ↔ 백엔드 간 HTTP 연동을 확인할 수 있는 최소 단위 엔드포인트를 기여하였습니다.
그래서 우선 아래 두 개 엔드포인트를 추가했습니다.
GET /experiment/agent/modelInfoPOST /experiment/agent/generate-content이 단계에서는
서비스/DB/LLM 연동은 전혀 하지 않고, 간단한 입력 값 검증 + Mock 응답만 반환하도록 구현했습니다.
이렇게 최소 컨트롤러부터 올려두어
마지막으로 제가 가장 오래 붙잡고 있었던 작업은 Model 관련 정보와 TargetEnvironment를 어떻게 저장할 것인가에 대한 DB 구조 개선이었습니다.
이 작업은 이슈를 해결하는 느낌으로 기존에 있던 문제를 해결하였는데요.
이 기여는 생각할 부분이 많아 많은 피드백을 통해 점점 다듬어졌습니다.
자잘자잘하게 멘토님과 메인컨테이너와 의논한 내용들이 많았지만 크게 3번의 시도로 나누어 정리해보았습니다.
표준 문서에서는 ModelInformation이 TargetEnvironment 리스트를 가진다고 정의하고 있습니다. 하지만 처음 코드를 봤을 때는 ModelInformation 쪽에 명시적인 ID/FK 구조가 없어서, 저는 이렇게 생각했습니다.
“그럼 내부에서는 ModelInformation과 연관 관계인 ModelRelatedInformation이 TargetEnvironment를 자식으로 가지는 구조로 설계하고, 외부 API에서는 그걸 풀어서 전달하면 되지 않을까?”
그래서 1차 시도에서는 ModelRelatedInformation ↔ TargetEnvironment 부모-자식 관계를 정의하고, 그 구조를 기준으로 아주 간단한 CRUD 테스트를 먼저 작성했습니다.
그리고 메인 컨테이너에게 두 가지 피드백을 받았습니다.
그래서 “표준 필드는 ModelInformation에 맞추고, 내부 구조는 조금 더 고민해 보자”는 상태로 1차 시도를 정리했습니다.
2차 시도에서는 리뷰 내용을 반영해서 방향을 바꿨습니다.
외부 스펙은 최대한 그대로 맞추고, DB 마이그레이션은 단계적으로 가져가자.
코드의 변경 단위는 최소한으로 가져가고 우선 최소한의 기능으로 작동하는 코드를 넣어두고 점점 보완하는 것이 목표였습니다.
그래서 우선
즉, 2차 시도에서는 API 스펙을 먼저 맞추고, DB 내부 구조는 완전하지 않아도 된다는 절충안이었습니다.
하지만 다시 메인컨테이너의 리뷰에서는 다음과 같은 추가 요구가 있었습니다.
이 피드백을 반영해서 3차 시도를 진행하게 됩니다.
⸻
3차 시도에서는 메인컨테이너에게 DB에서는 외부에 노출되지 않는 ID와 FK를 추가해도 된다는 허락을 받았으니 아예 DB 구조와 매핑 전략을 다시 잡았습니다.
“API는 표준에 맞게 깔끔하게 노출하고, DB에서는 정규화된 1:N 구조를 제대로 정의하자.”
핵심 변경점은 다음과 같습니다.
슬라이드 기준으로 정리하면 최종 구조는 이렇게 정리됩니다.
⸻
구조가 세 번 바뀐 만큼, 테스트도 고쳐 쓰기보다, 최종 구조 기준으로 다시 한 번 전부 점검했습니다.
테스트에서 확인한 것들은 대략 다음과 같습니다.
정리해보면, 이번 AIMLFW 기여는 다음과 같았습니다.
사실 기능적으로 정말 대단한 일을 하거나 큰 업데이트를 하진 않았지만 많은 일들과 병행하며 진행한 프로그램이라 제 나름대로는 만족이 되었습니다.
글로 표현할 수 없는 많은 일들이 있었고 많은 경험을 얻었습니다.
멘토님과 메인컨테이너가 많은 도움을 주셨고, 멘티님들과 많이 소통하며 즐거운 시간을 가졌습니다!
앞으로도 꾸준히 제가 재미있어 할 만한 오픈소스 프로젝트를 찾고 기여를 해봐야겠습니다!