민지(MINJI)의 운영체제, vShell에 대하여. (내용추가/편집됨)
며칠 전에 두 차례 게시했던 개인용 오프라인 환경의 LLM 시스템 MINJI 에 대한 추가 내용입니다.
처음 소개한 페이지는 https://okky.kr/articles/1562706 를 참조하세요.

vShell은 리눅스의 쉘 환경을 닮은 MINJI 시스템의 기본 운영체제 환경입니다.
사용자는 vShell을 이용하여 MINJI 시스템의 모든 기능을 제어하고 MINJI를 학습/추론 시킬수 있고, 이를 자동화 시킬수 있으며, 학습 과정에서 vCPU의 동작을 제어하기 위해 VLIW 코드를 작성하여 연동시킬수 있고, 필요한 기능이 있다면 vShell script 코드를 작성하여 응용프로그램 처럼 실행시킬수 있으며, 단위 스크립트 코드들을 라이브러리처럼 갖춘 다음 이 라이브러리 들을 호출하여 더 큰 기능을 구현할 수도 있습니다. (vShell의 명령어를 사용하여 스크립트 코드를 작성/실행시 내부적으로 중간코드로 변환하여 모든 명령을 룩업테이블에서 직접 변환/호출하여 실행되는데다, 기본적으로 정수와 고정소숫점 체계를 사용하여 웬만한 인터프리터 언어보다 고속으로 실행됩니다 : 사용자가 vShell의 코드를 작성후 save 하게되면 실시간으로 바이너리 파일인 ~.bin 파일이 생성되며, 사용자는 확장자 없이 이름만 적어주면 바이너리 파일이 실행됩니다.)
P.S : vShell 내부에 코드 작성을 지원하기 위한 인라인 에디터 기능이 내장되어 있습니다만, 사용하기 불편한 분들은 외부 에디터를 사용하여 코딩/편집 하셔도 무방하며 확장자만 ~.vsh로 정해 주시면 됩니다. 단, 외부 에디터로 작성된 코드는 반드시 인라인 에디터로 불러온 다음 save를 해 주셔야 바이너리 파일이 생성됩니다. (edit anycode*, list, save, exit, anycode : 실행)
(주* : 인라인 에디터로 외부 파일을 불러올때 확장자는 붙이지 않아도 됩니다)
사실, MINJI에 vShell을 내장한 이유 자체가 기존 A.I 시스템의 빡센 학습 환경을 극복하고 개발및 운영을 쉽도록 하기 위함이었습니다.
물론, 리눅스의 쉘 환경과 비슷하다 하여 똑같지는 않습니다.
우선 기본적으로 시스템의 내부 요소들 (의미셀, 토큰, 가중치, threshold등)을 제어하기 위한 다양한 명령들과, 테스트및 상태 확인을 위한 다양한 명령들이 있습니다.
그리고, 리눅스의 쉘 환경과 같이 터미널에서 직접 제어하거나 스크립트 코드로 작성하여 '간이 프로그래밍 언어'처럼 사용할 수 있는 명령어들이 60여종 정도 준비 되어 있습니다.(계속 늘어납니다)
그리고, 그 자체로 간이 프로그래밍 언어처럼 사용할 수 있도록 하기 위한 요소중 하나가 '스크립트 코드의 재활용' 입니다.
vShell의 명령어중 call 명령은 내부에서 서브루틴을 호출하기 위한 명령입니다.
예를들어 'call @sub1' 이라고 입력하면 내부에 sub1 이라고 라벨을 정한 위치의 스크립트를 실행합니다.
그런데 만약 call "sub1.vsh" 라고 입력하면 sub1.vsh 라는 파일명의 스크립트 코드를 실행합니다.
그리고, 처리 결과는 Result 라는 고정 명칭의 변수에 저장됩니다.
Result는 지역변수 관리영역의 맨 마지막 16바이트를 사용하며, MINJI에서 지원하는 모든 타입의 변수로 사용될수 있습니다.
참고로, 서브 스크립트 연산 결과인 Result를 사용할때는 Result.n, Result.f 등으로 취하려는 데이타 타입을 지정해 주어야 합니다.
(예제)
call “control.vsh”
nTarget = Result.n
print 결과는_%d_입니다. nTarget
그리고, vShell의 명령어에 대해 기억나지 않으면 manual 을 입력하면 명령어 들을 스크린에 표시해줌과 함께 vshell_manual.txt 라는 명칭으로 텍스트 파일을 생성합니다.
개인적으로 화면으로 지나가는 내용으로 만족하지 못해서 파일을 별도로 만들도록 했습니다
그외에 기본적인 사칙연산 외에 논리 연산과 시프트 등의 C 언어 수준의 다양한 연산 기능도 지원합니다.
물론, 단점도 C 언어와 비슷하게 존재합니다.
일반 스크립트 언어에서는 변수에 데이타 타입을 따지지 않고 기본적으로 부동소숫점 취급을 합니다만, vShell 에서는 C언어와 비슷하게 처리할 타입에 맞춰서 변수를 정해야 합니다.

* vShell 샘플코드 작성및 테스트 예제 :
[V] edit vshellTest
[vShell Command Input]: edit vshellTest
========================================== [ 💻 vShell 명령어 모드 ]
✍️ vShell 실시간 컴파일 에디터 모드 진입
스크립트: vshellTest.vsh / 바이너리: vshellTest.vbin
[명령어] list, del <n>, insert <n> <내용>, save, exit
==========================================
-> 💾 기존 파일 내용을 성공적으로 불러왔습니다. ('list' 로 확인 가능)
[V] list
[vShell Command Input]: list
--- [vshellTest.vsh] 현재 버퍼 내용 ---
1 | var Lf_봉급
2 | var Lf_월_이율
3 | var Lf_받을돈
4 | Lf_봉급 = 1000000
5 | Lf_월_이율 = 0.37
6 | Lf_받을돈 = (Lf_봉급 + (Lf_봉급 * Lf_월_이율)) * 12
7 | print 1년후_받을돈_:_%f Lf_받을돈
----------------------------------
[V] save
[vShell Command Input]: save
-> ⚙️ [vshellTest.vbin] 다형성(Polymorphism) VLIW 네이티브 컴파일 완료. (유효 명령어: 4개)
[V] exit
[vShell Command Input]: exit
==========================================
[vShell] 에디터 모드 종료. 일반 쉘로 복귀합니다.
==========================================
[V] vshellTest
[vShell Command Input]: vshellTest
-> [vShell] 지역 변수 'Lf_봉급' 등록 완료 (크기: 8 bytes, 오프셋: 0)
-> [vShell] 지역 변수 'Lf_월_이율' 등록 완료 (크기: 8 bytes, 오프셋: 8)
-> [vShell] 지역 변수 'Lf_받을돈' 등록 완료 (크기: 8 bytes, 오프셋: 16)
-> [vShell] 지역 변수 'Lf_봉급' 수식 대입 완료.
-> [vShell] 지역 변수 'Lf_월_이율' 수식 대입 완료.
-> [vShell] 지역 변수 'Lf_받을돈' 수식 대입 완료.
1년후 받을돈 : 16440000.001341
[V]
vShell에서 변수를 정할때 데이타 타입은 변수명의 첫 글자로 구분합니다.
n : 32비트 정수, N : 64비트 정수, u : 32비트 부호없는 정수, U : 64비트 부호없는 정수, f : 64비트 고정소숫점 (32비트정수 + 32비트소수), F : 128비트 고정소숫점 (64비트정수 + 64비트소수), S : 스트링 (길이지정가능, 지정 없을경우 256바이트)
변수 타입 (n, N, u, U, f, F, S) 앞에 붙은 'L'은 지역변수임을 가리킵니다.
MINJI 시스템에는 지역변수와 전역변수가 있습니다.
지역변수는 vShell 전용으로 스크립트 코드가 실행될때 자동으로 1KB가 배당됩니다(32비트타입 변수 256개분).
이 영역은 스크립트 코드가 실행될때 제공되며, 만약 코드 내에서 다른 스크립트 코드를 서브스크립트로 호출하게 되면 새로 1KB가 주어집니다.
이런식으로 서브 스크립트가 호출될때 마다 1KB씩의 지역변수 공간이 제공되며, 최대 16단계 까지 호출 할 수 있습니다.
전역변수는 파일연동 가상메모리(전원이 꺼져도 내용이 보존됩니다) 공간으로 1MB가 제공됩니다만, 원칙적으로 이 공간은 vCPU에서 사용하기 위해 제공된 공간입니다.
물론, vShell에서도 자유롭게 사용할 수 있습니다만, 기본적으로 서브스크립트를 호출할때 인수를 지정하여 메인 스크립트와 서브스크립트간의 자료 교환으로 사용하기 위한 용도로 사용하는 경우 외에는 지역변수를 주로 사용하기를 권장하고 있습니다.
전역변수로 제공하는 1MB의 공간이란 최대 40억개까지 확장 가능한 의미셀과 연동되어 동작하는 vCPU에서 공유하는 용도로는 매우 협소한 영역이기 때문입니다.
또 다른 특징으로, 샘플에서 보시듯 명령어 외에는 전반적으로 한글을 차별하지 않는다는 점입니다.
그 이유는 의미셀등 신경망 내부에서 한글을 사용할 일이 많기 때문입니다.
예를들어, 의미셀을 등록할때 개체의 구분을 쉽게 하도록 하기 위해 해당셀의 이름을 정하도록 하고 있습니다.
물론, 이름(alias)이란건 어디까지나 사용자가 구분과 사용을 쉽게 하도록 하기 위한것으로, 내부처리에는 영향을 미치지 않습니다. (시스템 내부에서는 32비트의 고유번호인 ID를 개체의 구별 용으로 사용합니다)
하지만, 사용자를 위해 전반적으로 alias의 사용을 지원합니다.
당연히 alias는 한글과 영문을 보두 지원합니다.
참고로, vShell의 스크립트 코드는 표현상 ‘스크립트 코드’라고 부르지만, 에디터로 코드 작성후 저장 단계에서 중간코드 형식의 바이너리 값으로 변환 저장되고, 실행시 중간코드 값을 실시간으로 테이블 룩업으로 분류하여 실행하는데다, 기본적으로 부동소숫점이 아닌 정수단위와 고정소숫점 체계의 연산을 처리하므로 과거 GWBASIC류의 인터프리터 언어보다 처리 속도는 월등히 빠릅니다.
