크롬 127 부터 window.ai 기능이 실험적으로 도입되었다. 이 기능을 이용해서 간단한 AI 기능을 사용할 수 있다. 실험적 기능이라 모두에게 적용되는 것은 아니고 세팅이 좀 복잡하다.
https://dev.to/grahamthedev/windowai-running-ai-locally-from-devtools-202j 사이트에 제시되는 방법을 사용해서 빠르면 10분(내 윈도우즈 PC는 설정후 10분 후에 사용이 가능했다.), 느리면 3~4일(내 회사 Intel Macbook은 토~일 요일 포함 4일 정도 소요 되었다. ) 후에 window.ai 기능을 사용할 수 있다.
매우 간단하 nano AI 기능이다. WebGPU 를 사용하기 때문에 좋은 그래픽 카드를 사용하면 가속을 받을 수 있다. Chrome 이 어떤 그래픽 카드까지 지원하는지 알 수 없으나 엔비디아는 확실히 지원하는 것 같다.
저기에 표시된 API 가 어느 순간 변경되어 버렸다.
// 초기 버전
const chatSession = await window.ai.createTextSession()
// 현재 동작하는 버전
const chatSession = await window.ai.assistant.create()
둘 중에 어느 것이 동작하는지 확인이 필요하다. (beta 기능도 아닌 실험적인 기능이라서 빠르게 API가 변경된 것 같다.)
인터넷에 찾아보니 사람들은 `Gemma 2B 2b-it-gpu-int4` 모델을 활용하는 거라고 추정하고 있다. 이 주소에서 https://www.kaggle.com/models/google/gemma/tfLite/gemma-2b-it-gpu-int4 에서 다양한 형태로 다운받을 수 있다. (chrome 에 있는 것은 gemini nano 로 보인다. https://huggingface.co/oongaboongahacker/Gemini-Nano 에 누가 올려났다. )
대충 코드를 만들었는데, 아래 처럼 하면 1번은 대화가 가능한 것 같다. 물론 대화 세션이 유지되게 하려면 좀 다른 방법이 필요한 것 같다. 그것까지는 잘 모르겠다.
<!DOCTYPE html>
<html>
<head>
<title>Test </title>
</head>
<body>
<textarea id="promp_area" rows="8" style="width: 800px;"></textarea>
<br/>
<button id="ask_btn">ASK</button>
<br/><br/><br/><br/>
<textarea id="promp_result" rows="16" style="width: 800px;"></textarea>
<script>
let chatSession;
const start = async function(){
chatSession = await window.ai.assistant.create();
}
start();
async function ask(){
console.log("==== ask start ====")
let promp_area = document.getElementById("promp_area");
let promp_result = document.getElementById("promp_result");
let promp_text = promp_area.value;
const stream = chatSession.promptStreaming(promp_text);
let result = "==== start ====\n"
let previous = '';
for await (const chunk of stream) {
const sub_result = chunk.slice(previous.length);
console.log(sub_result);
result += sub_result;
previous = chunk;
promp_result.value = result;
}
result += "\n==== end ===="
promp_result.value = result;
console.log("==== ask end ====")
}
const ask_btn = document.getElementById("ask_btn");
ask_btn.onclick = ask;
let promp_area = document.getElementById("promp_area");
promp_area.onkeydown = function(event){
const isAlt = event.altKey || event.metaKey;
if(event.key == "Enter" && isAlt){
ask();
}
};
</script>
</body>
</html>
javascript 코드를 물어 봤는데, 실제로 동작하는 코드를 만들어 냈다.
```자바스크립트 함수가 필요해. 특정 숫자를 입력으로 받고 소수인지 판단하는 isPrimeNumber 라는 함수를 만들어줘.```
라고 질문하자.아래 코드를 만들어 주었다.
==== start ====
```js
function isPrimeNumber(num) {
// 1과 같은 숫자는 소수가 아니다
if (num === 1) {
return false;
}
// 2부터 루트까지 소수 판별
for (let i = 2; i * i <= num; i++) {
if (num % i === 0) {
return false;
}
}
// 소수
return true;
}
```
==== end ====
이 코드 실제로 잘 동작했다.
그리고 더 나가서
```
자바스크립트 함수가 필요해. 특정 숫자를 입력으로 받고 소수인지 판단하는 isPrimeNumber 라는 함수를 만들어줘. 가능한 효율적으로 만들어줘.
```
라고 질문했더니 아래 코드를 만들었다.
==== start ====
```js
function isPrimeNumber(num) {
// 1과 같은 숫자는 소수가 아니다
if (num === 1) {
return false;
}
// 2부터 루트까지 소수 판별
for (let i = 2; i * i <= num; i++) {
if (num % i === 0) {
return false;
}
}
// 소수 판별 루트 단위로
let 판별 = Math.sqrt(num).floor();
for (let i = 3; i * i <= 판별; i += 2) {
if (num % i === 0) {
return false;
}
}
// 소수 판별
return true;
}
```
==== end ====
이건 Math.sqrt(num).floor() 이 구문에서 에러가 발생했다. 의도는 충분히 알 것 같다.
(몰랐는데 크롬 javascript 에서 한글 변수가 동작하네!!! 이건 몰랐다.)
이 정도면 초보 프로그래머 수준은 되는 것 같다.
물론 애도 세종대왕 맥북 던짐 사건에는 헛소리 한다.
```
세종대왕 맥북프로 던짐 사건 알려줘.
```
==== start ====
**세종대왕 맥북프로 던짐 사건**
세종대왕 맥북프로 던지기 사건은 1998년 9월 27일에 일어난 사건이다. 이 사건은 세종대왕이 맥북프로를 땅에 던져버린 것으로 알려져 있다.
이 사건의 배경에는 1997년 11월 10일에 일어난 세종대왕 유비리 폭행사건이 있다. 세종대왕 유비리 폭행사건은 세종대왕이 유비리에게 폭행을 가한 것으로 알려져 있다. 이 사건 이후 세종대왕은 폭력적이고 잔혹한 통치자로 널리 널렸다.
세종대왕 맥북프로 던지기 사건은 세종대왕이 폭력적이고 잔혹한 통치자로 널리 널리 널렸다는 것을 보여준 사건이다.
==== end ====
아직 API 가 변경중에 있고, 모델도 변경가능한 상태라 어떻게 일괄성을 유지해서 개발에 이용할 수 있을지는 잘 모르겠다. 그래도 생각보다 AI가 가까이 있다고 느껴지게 된다.