대표적인 AI 및 머신 러닝 플랫폼과 원활하게 연동하세요. Elastic의 생성형 AI 기능을 살펴보려면 무료 클라우드 체험을 시작하거나 지금 바로 내 기기에서 사용해 보세요.
이 게시물에서는 소프트웨어 애플리케이션에서 학술 논문을 구현하는 전략을 공유합니다. 다른 엔지니어들이 저희의 경험을 통해 배울 수 있기를 바라는 마음에서 Elasticsearch와 Lucene의 사례를 활용했습니다. 이러한 전략을 읽고 "하지만 이건 소프트웨어 개발일 뿐이야!"라고 생각할 수도 있습니다. 엔지니어로서 우리는 이미 올바른 관행과 도구를 갖추고 있으며, 새로운 도전에 적응하기만 하면 됩니다.
배경
Elasticsearch를 개발하는 동안, 우리는 때때로 이를 해결하기 위한 간단하거나 확립된 접근 방식이 없는 중요한 문제에 직면하게 됩니다. "흠, 이 문제를 다룬 학술 논문이 있나요?"라고 묻는 것은 당연한 질문입니다. 때로는 학문적 연구가 영감의 원천이 되기도 합니다. 새로운 알고리즘이나 데이터 구조를 제안하는 논문을 접하고 "정말 유용할 것 같다!"라고 생각하게 됩니다. 다음은 Elasticsearch와 Apache Lucene이 학술 작업을 통합하는 방법의 몇 가지 예입니다:
- 카디널리티 집계를 위한 HyperLogLog++
- 적응형 복제본 선택을 위한 C3 알고리즘
- 루씬에서 가장 가까운 벡터 검색을 위한 계층적 탐색 가능한 작은 세계 그래프(HNSW)
- 머신 러닝 분류를 개선하기위한 MIC 통계
- Lucene에서 더 빠른 인기 검색을 위한블록 최대 WAND
- ... 그리고 더 많은 것
학술 논문은 데이터 집약적인 시스템을 개발하는 엔지니어에게 매우 귀중한 자료입니다. 그러나 알고리즘 설명이 복잡하고 중요한 실용적인 세부 사항이 생략된 경우가 많아 구현하기가 어렵고 오류가 발생하기 쉽습니다. 예를 들어, 데이터 세트에 따라 결과가 크게 달라지는 머신 러닝 알고리즘을 어떻게 철저하게 테스트할 수 있을까요?
소프트웨어 종속성을 평가할 때와 마찬가지로 논문을 평가하세요.
새 소프트웨어 종속성을 추가하려면 신중한 평가가 필요합니다. 다른 패키지가 부정확하거나 느리거나 안전하지 않은 경우 우리 프로젝트도 마찬가지일 수 있기 때문입니다. 개발자는 종속성을 가져오기 전에 종속성의 품질을 평가해야 합니다.
구현을 고려 중인 학술 논문에도 동일하게 적용됩니다. 알고리즘이 논문에 발표되었기 때문에 정확하고 성능이 좋아야 한다고 생각할 수 있습니다. 그러나 검토 과정을 통과했더라도 학술 논문에는 문제가 있을 수 있습니다. 정확성 증명은 현실적이지 않은 가정에 의존하는 것일 수도 있습니다. 또는 '실험' 섹션에서 기준선보다 훨씬 더 나은 성능을 보여 주지만 이는 특정 데이터 세트에만 해당됩니다. 논문 품질이 뛰어나더라도 그 접근 방식이 프로젝트에 적합하지 않을 수 있습니다.
학술 논문에 대한 '의존성' 여부를 고려할 때는 소프트웨어 패키지에 대해 동일한 질문을 하는 것이 도움이 됩니다:
- 라이브러리가 널리 사용되고 '실전 테스트'를 거쳤나요? → 다른 패키지에서 이 문서를 구현한 적이 있으며 잘 작동했나요?
- 성능 벤치마크가 제공되나요? 정확하고 공정해 보이나요? → 논문에 실제 실험이 포함되어 있나요? 디자인이 잘 되어 있나요?
- 성능 개선이 복잡성을 정당화할 만큼 충분히 큰가요? → 논문이 강력한 기준 접근 방식과 비교되나요? 이 기준선을 얼마나 능가하나요?
- 이 접근 방식이 우리 시스템과 잘 통합되나요? → 알고리즘의 가정과 트레이드오프가 우리 사용 사례에 맞는가?
소프트웨어 패키지가 경쟁사와의 성능 비교를 발표할 때 항상 가장 빠르게 나오는 패키지가 있습니다! 제3자가 벤치마크를 설계했다면 더 균형 잡힌 결과를 얻을 수 있습니다. 학술 논문에도 동일한 현상이 적용됩니다. 알고리즘이 원본 논문에서 좋은 성능을 보였을 뿐만 아니라 다른 논문에서도 강력한 기준이 되는 것으로 나타난다면 그 알고리즘은 견고할 가능성이 매우 높습니다.
창의적으로 테스트하기
학술 논문의 알고리즘은 우리가 일상적으로 접하는 알고리즘 유형보다 더 정교한 동작을 하는 경우가 많습니다. 아마도 더 나은 속도를 위해 정확도를 희생하는 근사 알고리즘일 것입니다. 또는 대규모 데이터 세트를 받아 (때로는 예상치 못한) 결과를 생성하는 머신 러닝 방법일 수도 있습니다. 이러한 알고리즘의 동작을 간단한 방법으로 특성화할 수 없다면 어떻게 테스트를 작성할 수 있을까요?
불변값에 집중
단위 테스트를 설계할 때 알고리즘에 이 예제 입력을 제공하면 해당 출력을 가져야 한다는 식으로 예제 측면에서 생각하는 것이 일반적입니다. 안타깝게도 대부분의 수학 알고리즘은 예제 기반 테스트만으로는 그 동작을 충분히 커버할 수 없습니다.
Elasticsearch가 검색 요청을 처리할 노드를 파악하는 데 사용하는 C3 알고리즘을 살펴보겠습니다. 노드의 이전 서비스 및 응답 시간, 대기열 크기를 통합하는 미묘한 공식을 사용하여 각 노드의 순위를 매깁니다. 몇 가지 예를 테스트한다고 해서 공식을 제대로 이해했는지 확인할 수 있는 것은 아닙니다. 서비스 시간이 증가하면 노드의 순위가 감소하는가? 등 한 발 물러서서 불변성 테스트에 대해 생각해 보는 것도 도움이 됩니다. 대기열 크기가 0인 경우, 논문에서 주장한 것처럼 응답 시간에 따라 순위가 결정되나요?
불변값에 집중하면 여러 가지 일반적인 경우에 도움이 될 수 있습니다:
- 이 방법은 순서에 구애받지 않아야 하나요? 그렇다면 입력 데이터를 다른 순서로 전달해도 동일한 출력을 얻을 수 있습니다.
- 알고리즘의 어떤 단계가 클래스 확률을 생성하나요? 그렇다면 이 확률의 합계는 1이 되어야 합니다.
- 함수가 원점을 중심으로 대칭인가요? 그렇다면 입력의 부호를 뒤집으면 출력의 부호도 뒤집히게 됩니다.
C3를 처음 구현할 때 응답 시간 대신 응답 시간의 역수를 실수로 사용하는 공식에 버그가 있었습니다. 이는 느린 노드가 더 높은 순위를 차지할 수 있다는 것을 의미했습니다! 문제를 수정할 때 향후 실수를 방지하기 위해 불변 확인을 추가했습니다.
레퍼런스 구현과 비교
저자들은 논문과 함께 알고리즘의 구현을 공개할 예정입니다. (많은 저널에서 저자가 결과 재현을 위한 코드를 게시하도록 요구하기 때문에 논문에 실험이 포함된 경우 특히 그렇습니다.) 이 참조 구현과 비교하여 접근 방식을 테스트하여 알고리즘의 중요한 세부 사항을 놓치지 않았는지 확인할 수 있습니다.
가장 가까운 이웃 검색을 위한 Lucene의 HNSW 구현을 개발하는 동안, 논문 저자의 참조 라이브러리와 비교하여 테스트했습니다. 동일한 데이터 세트에 대해 Lucene과 라이브러리를 모두 실행하여 결과의 정확도와 수행한 계산 횟수를 비교했습니다. 이 수치가 거의 일치하면 Lucene이 알고리즘을 충실히 구현한다는 것을 알 수 있습니다.
알고리즘을 시스템에 통합할 때는 여러 코어로 확장하거나 휴리스틱을 추가하여 성능을 개선하는 등 수정 또는 확장을 해야 하는 경우가 많습니다. 먼저 "바닐라" 버전을 구현하고 레퍼런스와 비교하여 테스트한 다음 점진적으로 변경하는 것이 가장 좋습니다. 이렇게 하면 사용자 지정하기 전에 모든 핵심 부분을 캡처했다고 확신할 수 있습니다.
기존 알고리즘과의 결투
마지막 섹션에서는 테스트 불변수에 대한 또 다른 아이디어를 제시합니다. 알고리즘의 출력을 더 간단하고 이해하기 쉬운 알고리즘의 출력과 비교하는 것입니다. 예를 들어, 상위 결과에 표시되지 않는 문서를 건너뛰어 문서 검색 속도를 높여주는 Lucene의 블록 최대 WAND 알고리즘을 생각해 보세요. 모든 경우에 블록맥스 WAND가 어떻게 작동해야 하는지 정확히 설명하기는 어렵지만, 적용한다고 해서 상위 결과가 바뀌지는 않는다는 것은 알고 있습니다! 따라서 테스트에서는 여러 개의 무작위 검색 쿼리를 생성한 다음 WAND 최적화를 적용하거나 적용하지 않은 상태에서 실행하여 결과가 항상 일치하는지 확인할 수 있습니다.
이러한 테스트의 중요한 측면은 비교를 실행하기 위해 무작위 입력을 생성한다는 것입니다. 이를 통해 생각하지 못했던 사례를 연습하고 예상치 못한 문제를 발견할 수 있습니다. 예를 들어, BM25F 채점에 대한 Lucene의 무작위 비교 테스트는 미묘한 에지 케이스에서 버그를 발견하는 데 도움이 되었습니다. 알고리즘에 무작위 입력을 공급하는 아이디어는 컴퓨터 보안의 일반적인 테스트 기법인 퍼징 개념과 밀접한 관련이 있습니다.
Elasticsearch와 Lucene은 이 테스트 접근 방식을 자주 사용합니다. 두 알고리즘(TestDuelingAnalyzers, testDuelTermsQuery...) 간에 "결투" 를 언급하는 테스트가 표시되면 이 전략이 실행 중인 것입니다.
논문 용어 사용
다른 개발자가 여러분의 코드를 작업할 때는 해당 문서를 참조하여 세부 사항을 따라야 합니다. Elasticsearch의 HyperLogLog++ 구현에 대한 코멘트가 이를 잘 설명해줍니다: "논문을 읽지 않고 이 클래스가 하는 일을 이해하려고 하는 것은 모험적인 일로 간주됩니다." 이 메서드 주석도 좋은 예가 됩니다. 여기에는 학술 논문 링크가 포함되어 있으며, 원래 설명된 알고리즘에 어떤 수정 사항이 있었는지 강조 표시되어 있습니다.
개발자는 문서를 기반으로 코드를 이해하게 되므로 동일한 용어를 사용하는 것이 도움이 됩니다. 수학적 표기는 간결하기 때문에 일반적으로 '좋은 스타일'로 간주되지 않지만 논문의 맥락에서는 매우 명확한 이름이 될 수 있습니다. 학술 논문의 공식은 rS, muBarSInverse와 같은 암호화된 변수 이름을 Elasticsearch에서 접하게 되는 몇 안 되는 경우 중 하나입니다.
저자가 추천하는 논문 읽기 방법: 큰 커피와 함께.

작성자에게 이메일을 보낼 수 있습니다.
어려운 논문을 작성하다 보면 공식을 잘못 이해한 건지, 오타가 있는 건지 몰라 몇 시간 동안 고민할 때가 있습니다. 오픈 소스 프로젝트인 경우 GitHub 또는 StackOverflow에서 질문할 수 있습니다. 그렇다면 학술 논문은 어디에서 구할 수 있을까요? 작성자는 바빠 보이고 이메일에 짜증이 날 수 있습니다.
오히려 많은 학자들이 자신의 아이디어가 실용화되고 있다는 소식을 듣고 기뻐하며 이메일을 통해 기꺼이 질문에 답변해 줍니다. 그들이 잘 알고 있는 제품이라면 웹사이트에 애플리케이션을 등록할 수도 있습니다!
또한 학계에서 소프트웨어 개발과 동일한 많은 도구를 사용하여 공개적으로 논문을 토론하는 경향이 증가하고 있습니다. 문서에 소프트웨어 패키지가 함께 제공되는 경우 Github에서 일반적인 질문에 대한 답변을 찾을 수 있습니다. "이론적 컴퓨터 과학" 및 "교차 검증"과 같은 Stack Exchange 커뮤니티에는 인기 있는 논문에 대한 자세한 토론도 포함되어 있습니다. 일부 학회에서는 모든 논문 리뷰를 온라인으로 게시하기 시작했습니다. 이 리뷰에는 접근 방식에 대한 유용한 인사이트를 얻을 수 있는 저자와의 주고받는 토론이 포함되어 있습니다.
계속하기
이 게시물에서는 학술 논문 선택의 기본 사항에 중점을 두고 다음과 같이 설명합니다.
를 올바르게 구현하는 방법을 설명하지만 실제로 알고리즘을 배포하는 모든 측면을 다루지는 않습니다. 예를 들어 알고리즘이 복잡한 시스템에서 하나의 구성 요소에 불과한 경우 구성 요소의 변경이 엔드투엔드 개선으로 이어지도록 하려면 어떻게 해야 할까요? 알고리즘을 통합하는 과정에서 원본 논문에서 다루지 않은 상당한 수정이나 확장이 필요하다면 어떻게 해야 할까요? 이러한 주제는 향후 포스팅에서 더 많이 공유하고자 하는 중요한 주제입니다.




