paint-brush
탐험을 위한 소프트웨어: 발견의 균형 달성~에 의해@sinavski
333 판독값
333 판독값

탐험을 위한 소프트웨어: 발견의 균형 달성

~에 의해 Oleg SInavski10m2024/03/21
Read on Terminal Reader

너무 오래; 읽다

다음을 주장하는 게시물: - 연구 중에 너무 많은 생산 기술을 피합니다. 생산과 연구는 서로 다른 목표를 가지고 있습니다 - 대부분의 코드가 사라질 것이기 때문에 연구에서 "기술 부채"를 가져가는 것은 괜찮습니다. 예를 들어 코드 재사용을 위해 노력해서는 안 됩니다. - 하지만 연구원으로서 당신은 여전히 빠른 탐색, 빠른 분기 및 깔끔하고 간단한 코드에 투자해야 합니다.
featured image - 탐험을 위한 소프트웨어: 발견의 균형 달성
Oleg SInavski HackerNoon profile picture

나는 평생 연구에 종사했기 때문에 연구자들이 보기 흉한 코드를 작성한다는 고정관념을 알고 있습니다(예: 여기 , 여기 또는 여기 참조 ). 하지만 저는 우리가 고칠 수 있다고 생각했어요. 그렇죠? 그래서 저는 좋은 연구 프레임워크를 디자인하려고 여러 번 노력했습니다. 나는 내가 즐겨 읽는 소프트웨어 엔지니어링 서적과 블로그를 사용하여 인터페이스를 가져오고 멋진 추상화를 만들려고 노력했습니다.


그러나 그 모든 노력은 번번이 수포로 돌아갔습니다. 제가 작업한 대부분의 연구 소프트웨어는 프로덕션으로 전환되지 않았습니다(일부는 그랬지만). 누군가 나에게 간단한 진실을 말해주었다면 내 정신 건강에 좋았을 것입니다. 죽어가는 연구 코드는 실제로 일어나야 하는 일입니다 . 연구자들은 애초에 그것을 엔지니어링하는 데 많은 시간을 소비해서는 안 됩니다.


전문 소프트웨어 엔지니어는 항상 최고의 소프트웨어 방법을 사용하지 않는 연구원을 무시합니다. 연구 코드의 기준을 높이려는 게시물이 여러 개 있습니다(예: 이 훌륭한 게시물연구 코드 핸드북 ). 하지만 이 게시물은 다른 방향으로 진행됩니다. 최고의 소프트웨어 관행을 과도하게 사용하지 않고 대신 빠른 탐색에만 투자하는 방법을 논의합니다. 많은 아이디어를 빠르게 시도하는 것이 목표인 연구 중심 회사를 대상으로 합니다.

1. 전략적 기술 부채를 짊어진다

회사의 성공적인 연구 프로젝트는 탐색과 활용이라는 두 단계로 구성됩니다. "탐색"에서는 가능한 한 많은 다양한 솔루션을 시도하고 싶습니다. "활용" 중에는 최상의 솔루션을 강화하고 이를 유용한 제품으로 바꿔야 합니다.

탐사 중에 많은 프로젝트가 종료됩니다. 활용하는 동안에만 강력한 솔루션을 구축해야 합니다.

최적의 소프트웨어 관행은 둘 사이에 상당히 다릅니다. 그렇기 때문에 기업에서는 연구 부서와 제품 부서를 별도로 두는 경우가 많습니다. 소프트웨어 설계에 관해 일반적으로 읽을 수 있는 모든 책은 주로 두 번째 "이용" 단계에 관한 것입니다. 이 단계에서는 확장 가능한 제품을 위한 기반을 구축합니다. 여기에서 멋진 API, 로깅, 오류 처리 등 모든 디자인 패턴이 필요합니다.


그러나 첫 번째 "탐사" 단계에서는 영원히 지속될 기반을 구축하는 것이 아닙니다 . 실제로, 대부분의 노력이 살아남는다면 (정의에 따라) 충분한 탐색을 하지 않은 것입니다.


이 게시물의 많은 관행은 일반적으로 "기술 부채"가 되는 사례입니다. 깨끗하고 재사용이 가능하고 잘 추상화된 코드를 작성하지 않음으로써 얻을 수 있는 것입니다. 빚은 항상 나쁜 것인가? 우리는 대출이나 주택담보대출을 받지 않는 것을 선호하지만, 돈을 빌리는 것은 종종 인생에서 좋은 전략이 됩니다. 빨리 움직이고 나중에 이익을 얻으려면 빚을 지는 것이 좋습니다.

연구에서 소프트웨어 빚을 지는 것은 괜찮습니다. 모든 것을 갚을 필요는 없으며, 성공적인 연구 경로에 있는 소수에 대해서만 갚을 수 있습니다.

마찬가지로 기술 부채를 지지 않으면 연구 속도가 느려질 수 있습니다. 좋은 소식은 대부분의 경우 돈을 갚을 필요가 없다는 것입니다. 어쨌든 대부분의 연구 코드는 죽을 가능성이 높습니다. 따라서 평균적으로 귀하는 귀하가 짊어진 전체 기술 부채로 고통받지 않을 것입니다.

코드 재사용 반대 사례

많은 소프트웨어 아키텍처와 리팩토링 기술은 특히 코드 재사용성을 향상시키는 데 중점을 두고 있습니다. 코드 재사용에는 일반적인 단점이 있습니다. 그러나 프로덕션에서는 잘 알려진 이점보다 더 중요합니다(예를 들어 이 일반적인 게시물 참조). 연구 프로젝트에서 대부분의 코드는 망각될 운명입니다. 코드 재사용을 위해 노력하면 실제로 속도가 느려질 수 있습니다.


코드 재사용을 제한하는 것은 연구에 사용해도 괜찮은 기술적 부채 유형입니다. 제가 논의하고 싶은 코드 재사용 패턴에는 불필요한 종속성 추가, 코드 복사 붙여넣기, 많은 공유 연구 코드 유지, 조기 설계 투자 등이 있습니다.

새로운 것을 가져오기 전에 두 번 생각하세요

속도를 높여줄 잘 관리되고 버전화된 라이브러리를 알고 있다면 그것을 선택하십시오! 그러나 새로운 종속성을 도입하기 전에 그만한 가치가 있는지 판단해 보십시오. 추가될 때마다 의존성 지옥에 더 가까워집니다. 학습하고 문제를 해결하는 데 시간을 투자하게 됩니다. 이 간결한 게시물 에서 종속성의 더 많은 함정을 확인하세요.


다음과 같은 경우 무언가에 의존하는 것이 좋습니다.

  • 이미 사용했으므로 배울 것이 많지 않으며 대규모 커뮤니티, 좋은 문서 및 테스트가 있습니다.
  • 버전이 지정되어 있어 설치가 쉽습니다.
  • 마지막으로, 직접 구현할 수 있는 방법은 없습니다.

그러나 다음과 같은 경우 종속성에 주의하세요.

  • 빨리 사용하는 방법을 알 수 없거나, 아주 새로운 것(또는 아주 오래된 것)이거나, 아무도 모르는 것 같습니다. 문서나 테스트가 없습니다.

  • 그것은 귀하의 모노레포에서 왔으며 다른 팀에 의해 지속적으로 변경되고 있습니다.

  • 다른 많은 종속성과 도구를 가져옵니다. 아니면 설치가 어렵나요?

  • 그리고 마지막으로 당신(또는 일부 LLM)이 몇 시간 안에 이 코드를 작성할 수 있다고 생각합니다.


명시적인 종속성 대신에 다음 주제인 “ 약간 복사하는 것이 약간의 종속성보다 낫습니다 ”라는 멋진 Go 속담을 따를 수 있습니다.

Copypaste를 사용하면 자유롭게 실험할 수 있습니다.

복사 붙여넣기는 빠르며 때로는 연구 중에 가장 좋은 도구입니다.

어떤 사람들은 “ 복사 붙여넣기가 불법이어야 한다 ”고 말합니다. 그러나 놀랍게도 나는 그것을 꽤 자주 찬성하는 입장을 보였습니다. Copypaste는 탐색 단계에서 최적의 선택이 될 수 있습니다.


코드베이스의 다른 부분에서 많이 사용되는 함수에 의존하는 경우 쉽게 변경하는 것을 잊어버릴 수 있습니다. 누군가를 위해 무언가를 망칠 가능성이 높으며 코드 검토 및 수정에 귀중한 시간을 소비해야 합니다. 그러나 필요한 코드를 폴더에 복사하여 붙여넣으면 원하는 모든 작업을 자유롭게 수행할 수 있습니다. 이는 실험이 예외가 아닌 표준이 되는 연구 프로젝트에서 큰 문제입니다. 특히 변경 사항이 모든 사람에게 유용할지 확실하지 않은 경우에는 더욱 그렇습니다.


복사 붙여넣기에는 딥러닝 코드베이스가 가장 적합하다고 생각합니다. 일반적으로 모델과 해당 교육을 설명하는 데 필요한 코드의 양은 그리 크지 않습니다. 그러나 동시에 그것은 매우 미묘하고 일반화하기 어려울 수 있습니다. 공유 가능한 훈련 스크립트는 관리하기 어려운 크기로 커지는 경향이 있습니다. 예를 들어 Hugging Face transformers Trainer에는 4,000개 이상의 라인이 있습니다. 흥미롭게도 트랜스포머는 모델 수준에서 복사 붙여넣기를 선택했습니다. "단일 파일 모델" 정책에 대한 이유가 담긴 게시물을 확인해 보세요. 끝 부분에서 복사 붙여넣기의 아름다움에 대한 더 많은 리소스를 확인하세요.


복사 붙여넣기의 대안은 지점에 머무르는 것입니다. 하지만 팀워크에 너무 많은 오버헤드가 발생하는 것 같습니다. 또한, 복사 붙여넣기의 아름다움에 관한 여러 게시물을 더 찾았습니다. 결론에서 더 많은 게시물을 확인하세요.

공유된 연구 코드를 유지하는 것은 어렵습니다.

많이 사용되는 공유 코드를 유지 관리하려면 많은 작업이 필요합니다. Pytorch 버전에 대해 표시된 torch.nn.Module 파일 행 수를 살펴보세요. 가장 발전된 연구 팀조차도 복잡성을 제어하는 데 어려움을 겪고 있음을 알 수 있습니다.

PyTorch 버전에 따른 torch.nn.Module 파일 길이. 점점 더 단순해지고 있지 않습니다.

대규모 공유 연구 코드를 유지하는 데 필요한 시간과 리소스를 과소평가하지 마십시오. 연구 라이브러리를 많이 사용할수록 더 복잡해집니다. 모든 연구 방향은 사용 사례가 약간 다르기 때문에 일반적인 도서관보다 빠르게 발생합니다. 무엇을 다시 기부할 수 있는지에 대해 매우 엄격한 규칙을 설정하세요. 그렇지 않으면 공유 코드가 취약해지고 수많은 옵션, 버그가 있는 최적화 및 엣지케이스로 인해 무성해집니다. 대부분의 연구 코드가 소멸되므로 이 모든 추가 복잡성은 다시는 사용되지 않습니다. 공유 코드 중 일부를 삭제하면 실제 연구를 수행할 시간이 확보됩니다.

코드 재사용이 아닌 탐색을 위한 디자인

프로덕션 환경에서도 코드의 미래 보장을 너무 많이 원하지 않는다는 것은 어느 정도 사실입니다. 요구 사항을 충족하는 가장 간단한 솔루션을 구현해 보십시오. 그러나 프로덕션 코드에는 항상 고려해야 할 유지 관리 측면이 있습니다. 예를 들어 오류 처리, 속도, 로깅, 모듈화는 일반적으로 고려해야 할 사항입니다.


연구 코드에서는 그 어느 것도 중요하지 않습니다. 당신은 가능한 가장 빠른 방법으로 아이디어가 좋은지 나쁜지 빠르게 증명하고 계속 진행하기를 원할 뿐입니다. 따라서 모듈이나 API 없이 이를 달성하는 지저분한 단순성은 완전히 괜찮습니다!


다음과 같은 조기 소프트웨어 투자에 귀중한 시간을 낭비하지 마십시오.

  • 프로젝트 초기에 구성 요소 인터페이스를 만드는 것입니다. 스스로 만든 인위적인 제약 조건에 맞추는 데 너무 많은 시간을 소비하게 됩니다.
  • 딥 러닝 솔루션을 시작하기 전에 딥 러닝 교육 인프라 최적화
  • 프로덕션 구성/팩토리/직렬화 시스템 또는 기본 클래스를 사용합니다. 프로토타이핑 중에는 해당 기능이 필요하지 않은 경우가 많습니다.
  • 지나치게 엄격한 린팅 및 유형 검사 시스템. 빠르게 변화하는 일회용 연구 코드를 늦출 이유가 없습니다.

2. 빠른 탐색에 투자하세요

연구 프로젝트의 목표는 새로운 해결책을 찾는 것입니다. (정의상) 그것이 어떻게 생겼는지 아는 사람은 아무도 없습니다. 이는 정보가 제한된 복잡한 연구 환경에서의 최적화 프로세스와 유사합니다. 좋은 최소값을 찾으려면 많은 경로를 시도하고 좋은 경로와 나쁜 경로를 인식하고 로컬 최소값에 갇히지 않아야 합니다. 이 모든 것을 빠르게 수행하려면 때로는 기술 부채를 지는 대신 소프트웨어에 투자해야 합니다.

공통 경로 속도 향상

연구 프로젝트의 일반적인 부분을 가속화하는 데 투자하세요.

시도해보고 싶은 다양한 연구 경로가 있습니다. 대부분의 경로에서 시간을 단축할 수 있는 디자인, 라이브러리 또는 최적화가 있습니까? 시도하려는 아이디어를 항상 모두 알 수는 없기 때문에 지나치게 엔지니어링하지 않도록 주의해야 합니다. 이는 모든 프로젝트에 매우 맞춤화되어 있지만 다음은 몇 가지 예입니다.


  • 심층 네트워크를 교육하는 경우 교육 인프라에 투자하세요. 훈련 중에 빠르고 안정적으로 수렴할 수 있는 하이퍼파라미터를 찾아보세요.
  • 모든 실험에서 다른 모델을 사용해야 하는 경우 신속하게 모델을 교체할 수 있는 방법을 알아내십시오(예: 간단한 공장 시스템을 사용하거나 복사하여 붙여넣기).
  • 모든 실험에 매개변수가 너무 많아 관리하기 어려운 경우 멋진 구성 라이브러리에 투자하세요.

빨리 분기해라

새로운 연구 경로를 시작하는 속도에 투자하세요. 해결책을 찾기 위해서는 다양한 방향이 필요합니다.

연구자들은 새롭고 다양한 아이디어를 신속하게 시작할 수 있어야 합니다. 프로젝트 초반에는 쉬운 것 같습니다. 그러나 사람들이 자신이 좋아하는 연구 경로에 확고히 자리잡게 되면서 점차적으로 그것은 점점 더 어려워졌습니다. 이를 해결하려면 문화적, 조직적 변화가 필수적이다. 너무 많은 돈과 감정을 투자하기 전에 전망이 좋지 않은 연구를 중단하는 과정이 있어야 합니다. 정기적인 데모 데이와 동료 기술 검토는 이러한 목적을 위한 효과적인 전략이 될 수 있습니다. 사람들이 새롭고 빛나는 아이디어에 뛰어드는 것과 현재 프로젝트를 적절하게 마무리하는 것 사이의 균형을 찾는 것도 중요합니다.


그러나 이것은 소프트웨어 게시물이므로 새 프로젝트를 쉽게 확장할 수 있는 몇 가지 방법은 다음과 같습니다.

  • 평가 코드를 알고리즘에서 분리하세요. 평가는 일반적으로 연구 방향보다 더 안정적입니다.
  • 백지 상태에서 새 프로젝트를 시작하는 것을 받아들이되 어떤 구성 요소가 재사용되는지 주의 깊게 살펴보세요. 모듈화하고 정리하는 것은 좋은 투자입니다.
  • 새로운 연구 프로젝트에서는 가장 혁신적이고 위험한 구성 요소를 먼저 구현하십시오. 이를 통해 향후 소프트웨어 설계를 이끄는 병목 현상의 대부분을 식별합니다.

신호 대 잡음비 증가

버그와 비결정성은 연구 프로젝트를 탈선시키고 결과를 결정적이지 않게 만들 수 있습니다.

시끄럽고 버그가 많은 코드로 인해 결과가 너무 모호하고 결정적이지 않아 전체 프로젝트가 시간 낭비가 됩니다. 지나치게 엔지니어링해서는 안 되지만 다음과 같은 간단한 경험 법칙을 따르면 지저분한 코드를 쉽게 피할 수 있습니다.


  • 부작용이 있는 코드 피하기

  • 클래스보다는 함수가 기본값입니다. 클래스에서는 캡슐화와 상속을 선호합니다.

  • 함수/클래스/모듈의 길이를 최소화합니다. if 문 수 최소화

  • Python을 잘 알지만 간단한 기술을 사용하십시오. 메타클래스, 데코레이터 및 함수형 프로그래밍의 지적 잡초에 빠지는 유혹에 저항하십시오.


서로 다른 실행 중에 서로 다른 결과를 생성하는 소프트웨어는 작업하기 까다롭습니다. 불운한 씨앗을 바탕으로 중요하지만 잘못된 결정을 내렸다면 회복하는 데 많은 시간을 낭비하게 될 것입니다. 비결정적 소프트웨어를 다룰 때의 몇 가지 팁은 다음과 같습니다.


  • 잡음이 알고리즘에서 나오는지 아니면 평가에서 나오는지 이해합니다. 소음원은 복합적이므로 완전히 결정적인 평가를 위해 노력해야 합니다.
  • 실제로 재현 가능한 스크립트를 얻을 때까지 무작위성의 원인을 찾는 것을 멈추지 마십시오. 임의의 시드를 모두 찾은 후에는 데이터나 부작용이 있는 일반 함수에서 노이즈가 발생할 수 있다는 점을 기억하세요.
  • 시드를 다양화하고 결과의 기준 차이를 결정합니다. 통계적으로 유의미하지 않은 결과에 대해 결정을 내리지 마십시오.

결론

핵심은 연구 코드에 대한 이 게시물 에서 나왔습니다.


“코드가 핵심이 아니기 때문에 [좋은 소프트웨어 설계]에 신경 쓰지 않아도 됩니다. 코드는 필요한 답을 얻는 도구입니다.”


훌륭한 코딩 기초를 갖추는 것은 매우 중요합니다. 하지만 결국에는 탐구와 실제로 유용한 제품이 중요합니다. 연구에 프로덕션 소프트웨어를 너무 많이 사용하면 새로운 것을 발견하는 데 필요한 시간을 낭비하게 됩니다. 대신, 탐색 과정을 느리게 만드는 것이 무엇인지 찾아보세요. 빠른 분기, 결과 도출 시간, 잡음 없는 코드 정리에 투자하여 연구 경로의 속도를 높이세요.


코드 재사용에 대해 완전히 반대하는 것은 미친 짓입니다. 코드 재사용은 균형 잡힌 활동이어야 한다는 점을 지적하고 싶습니다. 연구에서는 프로덕션에서보다 폐기되는 코드의 비율이 더 큽니다. 저울은 재사용에 대해 더욱 기울어졌습니다. 다음은 코드 재사용의 함정이 있는 몇 가지 훌륭한 게시물입니다.


다음은 복사 붙여넣기 관행을 주장하는 몇 가지 게시물입니다.

읽어 주셔서 감사합니다! 약간 논란의 여지가 있는 부분도 있는 것 같으니 댓글로 알려주세요!


여기에도 나타납니다.