Skip to content

Separate Role Learning

kimjooyoon edited this page Oct 11, 2026 · 6 revisions

비교와 분기를 따로 배우면 나아질까

Gooo 함수 안에 두 개의 스위치가 있다고 생각해 봅시다. 하나는 비교식의 순서, 다른 하나는 조건을 만족했을 때 실행할 계산입니다. 작은 모델이 스위치를 고르면 컴파일러가 실제 본문을 조립하고 예시 출력과 중간 조건을 확인합니다.

이번에는 두 스위치를 한 모델이 고르는 방식과, 각각 별도 모델이 맡는 방식을 비교했습니다. 모델을 나누면 다른 역할을 배우기 쉬워질 수 있다는 가설이었습니다. 프로토콜과 소스를 먼저 공개한 뒤 세 모델을 각각 한 번 학습했습니다.

결과

관측 고정 순서 공동 모델 역할별 두 모델
관련 평가에서 첫 본문 성공 32/128 30/128 30/128
학습에 쓴 문서에서 첫 성공 16/64 16/64 18/64
학습에서 제외한 계산 유형 16/64 16/64 18/64
최대 네 후보 뒤 최종 검사 충족 256/256 256/256 256/256
전체 후보 검사 수 640 637 635
전체 모델 호출 수 0 256 512
조립 구간 총시간 28.177ms 64.160ms 98.401ms
배포하는 가중치 배열 없음 76,136바이트 152,272바이트

역할 분리로 관련 평가에서 8개가 개선되고 8개가 악화됐습니다. 모델 호출과 용량은 두 배가 됐으므로 이 구성을 기본값으로 채택할 근거가 부족합니다.

점수는 움직였지만 선택은 그대로였다

관련 평가에는 소스와 기대 출력이 같고 중간 조건만 달라지는 64쌍이 있습니다. 조건을 바꾸면 두 스위치도 모두 바뀌어야 합니다. 두 학습 방식 모두 모든 쌍에서 점수는 변했지만, 처음 고른 스위치는 어느 쌍에서도 바뀌지 않았습니다.

이 관측을 따로 남긴 이유는 모델 점수가 조금 움직이는 것과 요구를 반영해 실제 프로그램이 바뀌는 것 사이에 차이가 있기 때문입니다. 앞으로도 출력·중간 조건· 처음 고른 본문·최종 충족 여부를 각각 확인하려고 합니다.

직접 반환과 변수 대입으로 표현한 96쌍은 모델 입력·점수·후보 순서가 같았습니다. 여러 쌍은 같은 문서를 공유합니다. 쌍의 개수를 더해 표본이 늘었다고 해석하면 안 됩니다.

내 PC에서 든 비용

Apple M4, 논리 코어 10개, RAM 16GiB 환경에서 전체 원래 실행은 50.62초, 최대 메모리는 54.05MiB였습니다. CPU 시간은 사용자 49.39초와 시스템 0.34초입니다. 벽시계 시간으로 나누면 평균 한 코어의 약 98.2%에 해당합니다. 실행 전후 컴퓨터 전체 CPU 사용률 차이는 측정하지 않았습니다.

모델 한 번의 응답 중앙값은 공동 모델 105.063µs, 비교 모델 103.792µs, 분기 모델 102.834µs였습니다. 역할 분리는 두 번 호출하므로 하나의 응답 시간만으로 전체 정책의 지연을 설명할 수 없습니다. 이 작은 계산에서는 고정 순서가 더 빨랐습니다.

이 결과가 적용되는 범위

기존의 세 계산 템플릿과 알려진 한글·영문 표현을 사용하고 상수와 문서 식별자를 바꿨습니다. 학습 문서 64개, 관련 평가 128개, 제외한 유형 64개입니다. 각 문서에는 출력 예시 8개와 중간 조건 3개, 따로 기록한 출력 검사 16개와 조건 검사 3개가 있습니다. 최종 256/256은 이 유한한 검사와 네 가지 본문 후보에 대한 성적입니다.

조립 시간에는 모델 판단·기록 쓰기·컴파일·작성된 검사 실행이 들어갑니다. 소스 변환·초기 후보 수집·학습·별도 최종 검사는 제외합니다. 이번 생산자는 네 후보를 점수순으로 정렬하는 전용 경로를 사용하므로 앞선 실험과 시간 차이를 직접 비교하기 어렵습니다. Gooo에서 읽은 본문을 SDK로 실행했고 생성된 Gooo·Go도 보관했습니다.

공개 자료와 다음 질문

256개 소스, 768개 조립 기록, 순서를 포함한 사건 3,448개와 실패·손실·비용을 남겼습니다. 검산 코드는 재학습이나 새 모델 판단 없이 기록의 일치 여부를 확인합니다. 공개 SDK·컴파일러의 기본 모델은 유지합니다. 원래 push·PR CI가 통과한 뒤 SDK main의 ebae7adf에 정상 병합했습니다.

다음 질문은 중간 조건이 각 선택에 어떤 형태로 전달돼야 실제 선택을 바꾸는가입니다. 모델 수를 늘리는 것만으로 이번 문제는 풀리지 않았습니다. Gooo가 요구와 허용된 선택을 명시하고, 조립 결과의 부족한 부분을 보여 주는 기능은 계속 다듬을 수 있습니다.

후속으로 읽은 입력 표현

원래 기록만 다시 읽어 조건을 바꾼 쌍의 입력 배열을 비교했습니다. 관련 평가 64쌍은 개별 조건 행이 모두 달랐지만, 32개 원시 필드를 단순 평균하면 모든 쌍이 같았습니다. 예를 들어 기준값 167에서 입력은 166·167·168이고, 어느 목표든 참 한 개·거짓 두 개입니다. 각 열의 평균만으로는 참을 요구하는 입력이 어느 쪽인지 구분하기 어렵습니다.

현재 구현에는 입력 바이트와 기대값의 부호를 곱한 추가 필드가 있습니다. 이 필드의 평균은 모든 쌍에서 달라졌고, 가장 큰 좌표 차이는 약 0.00520833이었습니다. 학습 32쌍에서도 같았으며, 출력도 함께 달라지는 affine 32쌍은 따로 집계했습니다.

이 계산은 학습된 행 인코더 앞의 단순 산술 평균입니다. 실제 모델은 각 행을 학습된 가중치와 tanh로 처리한 뒤 모으고 소스 정보와도 결합합니다. 원래 기록의 모델 점수도 이미 달라졌습니다. 따라서 이 관측만으로 모델 내부에서 정보가 완전히 사라졌다거나 학습 실패의 원인을 찾았다고 말할 수는 없습니다.

검산 소스·고정 원본 지문·전체 쌍별 결과를 공개했습니다. 이번 읽기에서 학습·모델 판단·후보 실행은 모두 0회입니다.

다음 비교에서는 학습량을 고정하고, Gooo의 비교식과 각 조건 입력의 관계를 더 직접적으로 전달하는 표현을 검토할 수 있습니다. 기존 표현·새 표현을 쓰는 작은 모델과 결정론적 조건 처리의 비용을 함께 비교해야 합니다. 선택이 바뀌었는지, 검사하지 않은 사례가 얼마나 남는지, 전체 조립 비용이 어떤지도 함께 봅니다. 아직 이 후속 비교는 실행하지 않았습니다.

조건 관계를 담는 입력 구현

SDK PR65에 다음 실험용 입력을 구현했습니다. x < 167의 사례를 입력이 167보다 작은지·같은지·큰지로 나누고, 각 구간에서 참과 거짓을 몇 번 요구했는지 따로 셉니다. 참의 개수가 같아도 어느 구간에서 참을 요구했는지 남습니다. 정수는 빼거나 실수로 바꾸지 않고 그대로 비교해 큰 정수에서도 경계가 흐려지지 않게 했습니다.

모델에 전달할 배열은 16개 float32, 64바이트입니다. 준비된 소스·설명·향후 모델과 작업 메모리는 별도입니다. 직접 반환과 변수 대입은 같은 관계 배열을 만들고, 빈 조건은 빈 증거로 남습니다. 지원하는 범위를 벗어나면 이유를 표시합니다. 기존 가중치는 기존 입력을 계속 씁니다.

inspect -condition-relations로 볼 수 있으며, 입력 배치와 사용법에 지원 범위를 적었습니다. 실제 공개 SDK 예제의 세 조건을 읽어 두 선택에서 관계가 일치함을 확인했습니다. 이 읽기는 모델 호출·후보 실행·학습 갱신이 모두 0회입니다. 로컬 회귀·동시 실행·정적 검사와 원래 push·PR CI를 통과해 SDK main의 eb013ff6에 병합했습니다. 병합 후 CI38098231748도 통과했습니다. 후속288개 실험에서 관련 첫 선택은32/128에서64/128로 늘었습니다. 간단한 규칙도 같은 수를 맞혔고 비용은 더 적었습니다. 부분 결과와 실패를 함께 기록했습니다.

Gooo

배우기

직접 다뤄 보기

원리와 개발

공개 코드와 모델

Clone this wiki locally