들어가며

앞선 글에서 RAG에 대해 DBA의 관점으로 간략하게 설명을 했습니다.
(RAG(검색 증강 생성)이란 글 참고)
ORACLE DB에서 RAG를 사용하는 방법에 대해 알아보겠습니다.
제가 테스트 한 버전은 23AI Free 버전이므로 추후 EE버전에서는 내용이 달라질 수 있습니다.

실습 시나리오

오라클에서 LOCAL LLM OLLAMA 사용하여 EXAONE MODEL RAG(증강검색) 하는 테스트입니다.
대법원선고중요판결요지 라는 문서에 내용을 Chunk Embbeding 시켜 Vector 값을 가진 테이블을 만들었습니다. 테이블의 데이터를 사용해서 EXAONE LLM Model 질의를 하는 내용으로 테스트 내용을 작성했습니다.

대법원선고중요판결요지파일은 아래의 url 링크를 통해 다운받아서 사용하세요.
파일명 : law240830(8.29.판결).pdf 다운로드 링크

실습

1. 실습 테이블 생성

위에 선고중요판결요지라는 파일을 서버에서 불러와 임베딩하여 Vector값으로 컬럼이 포함된 테이블로 생성합니다.
쿼리 가장 아래에 있는 embed_vector clob 이라는 쿼리 내용중 clob 타입을 vector 했을 시에 테이블에 데이터가 보이지 않는 문제가 발생하여 clob select 절에서 to_vector함수를 사용하여 다시 벡터화 시켰습니다.

create table dre.rag_test as
select embed_id,embed_data,to_vector(embed_vector) as embed_vector
  FROM (select 
dbms_vector_chain.utl_to_text(TO_BLOB(bfilename('DOC_DIR',a.file_name))) AS DOC_content_blob
from (values('대법원선고중요판결요지_240829.pdf')) a (file_name) ) dc 
CROSS JOIN TABLE (
                 dbms_vector_chain.utl_to_embeddings(
                 dbms_vector_chain.utl_to_chunks(
                 dbms_vector_chain.utl_to_text(dc.DOC_CONTENT_BLOB)
                    ,json('{"by":"characters","max":"250","split":"none","normalize":"all","LANGUAGE":"KOREAN"}')),
                        json('{"provider":"database", "model":"ONN.DISTILUSE_BASE_MULTILINGUAL_CASED_V2"}'))) t
CROSS JOIN JSON_TABLE(t.column_value, '$[*]' COLUMNS (embed_id NUMBER PATH '$.embed_id', embed_data VARCHAR2(1000) PATH '$.embed_data', embed_vector clob PATH '$.embed_vector')) AS et;

 

2. HOST_ACL 등록

LOCAL LLM 서버와의 통신을 위해 HOST_ACL 등록합니다.

BEGIN
    dbms_network_acl_admin.append_host_ace(
        host =>'172.17.12.116',
        LOWER_PORT =>'9301',
        UPPER_PORT =>'9301',
        ace => xs$ace_type(
           privilege_list => xs$name_list('http', 'http_proxy'),
           principal_name => 'DRE',
           principal_type => xs_acl.ptype_db)
    );
END;
/

 

3. ACL 등록 통신 Test

SELECT * FROM  DBA_HOST_ACES ACES;
select utl_http.request('http://172.17.12.116:9301') from dual;
#쿼리 결과
Ollama is running

 

4. CREDENTIAL 생성

LLM API key 관리를 위해 CREDENTIAL 오브젝트 생성합니다.

declare
	  v_params json_object_t;
	  v_name varchar2(1000) :=  'EXAONE_CRED';
	  v_api_token varchar2(1000) := 'ollama-key'; 
	begin
	   v_params := json_object_t();
	   v_params.put('access_token',v_api_token); 
	   begin
	        DBMS_VECTOR_CHAIN.DROP_CREDENTIAL ( CREDENTIAL_NAME  => v_name);
	   exception 
	     when others then
	        null;
	   end;
	   
	   DBMS_VECTOR_CHAIN.CREATE_CREDENTIAL ( CREDENTIAL_NAME => v_name, PARAMS => json(v_params.to_string));
	end;
/

 

5. LLM 테스트

ORACLE에서 LLM 서버에 질의를 연결상태를 점검합니다. LLM모델은 exaone3.0:8b 입니다.

declare
  input clob;
  params clob;
  output clob;
begin
  utl_http.set_body_charset('UTF-8'); 
  input := '안녕 exaone3.0:8b 모델에 대해 설명해줘';
  params := '
{
  "provider": "OpenAI",
  "credential_name": "EXAONE_CRED",
  "url": "http://172.17.12.116:9301/v1/chat/completions",
  "model": "exaone3.0:8b",
  "context_length" : 2048
}';
  output := dbms_vector_chain.utl_to_generate_text(input, json(params));
  dbms_output.put_line(output);
  if output is not null then
    dbms_lob.freetemporary(output);
  end if;
exception
  when OTHERS THEN
    
    DBMS_OUTPUT.PUT_LINE (SQLERRM);
    DBMS_OUTPUT.PUT_LINE (SQLCODE);
end;
/
#질의 결과
-------------------------[Start Time: 2024/09/19 15:24:39]-------------------------
SQL> 안녕하세요! LG AI 연구원에서 개발한 EXO(EXpert Operating System) 3.0 기반의 8B 모델, EXAONE 3.0에 대해 설명해드릴게요.

### 주요 특징 및 장점:
1. **고성능 언어 이해 능력**:
   - 한국어와 영어를 포함해 다양한 자연어 처리 작업에서 우수한 성능을 자랑합니다.
  
2. **초거대 AI 모델 기반**: 
   - 8x Nvidia A100 GPU로 학습되었으며, 약 6TFLOPS의 연산 능력을 가집니다. 이는 기존 초거대 인공지능 대비 효율적이고 강력한 계산력입니다.
    
3. **전문 지식 통합**:
   - 방대한 양의 전문 문서 데이터를 바탕으로 다양한 산업의 최신 정보와 전문 지식을 습득할 수 있습니다. 
  
4. **생성적 AI 능력**:
   - 창작 활동 (예: 소설 작성, 음악 작곡 등)에도 뛰어난 성능을 보입니다. 이는 모델이 단순히 데이터를 분석하는데 그치지 않고 새로운 지식과 콘텐츠를 생성해 낼 수 있음을 의미합니다.
    
5. **한국어 특화 학습 모델**: 
   - 한국어에 최적화된 언어 모델로 감정 분석, 번역 작업 등에서도 우수한 성과를 보이며, 멀티모달 데이터 처리 기능이 강화되어 이미지 인식까지 확장할 수 있습니다.
  
6. **데이터 학습 윤리 및 프라이버시 준수**: 
    - 개인정보 보호 규정과 윤리적인 AI 개발 가이드라인을 철저히 준수하여 안전하게 활용 가능합니다.
   
### 결론적으로,
EXAONE 3.0은 여러 산업의 전문 작업 지원, 창의성 발휘 등 다양한 방면에서 효과적으로 사용될 수 있는 차세대 인공지능 모델입니다. 여러분께서 필요로 하시는 특정 분야나 적용 사례가 있다면 더 구체적인 설명도 가능하니 말씀해 주세요!

 

6. RAG사용을 위한 함수 생성

LLM모델은 위의 테스트에서 사용한 exaone3.0:8b 이고, Oracle DB안에 로드한 Embbeding Model distiluse_base_multilingual_cased_v2 사용하여 임베딩했습니다.

펑션의 내용을 보면 p_user_question 이라는 변수를 사용자에게 입력 받아옵니다.
입력받은 데이터를 v_model_params JSON 타입으로 작성된 모델환경으로 질의를 날립니다.
사용자 질의 내용은 오라클 안의 임베딩 모델을 통해 사용자 질의 쿼리 벡터를 생성하고, 쿼리 벡터를 사용하여 DRE.RAG_TEST라는 테이블에 VECTOR_DISTANCE 함수로 벡터거리를 계산합니다.
v_k_stop_count 파라미터의 값만큼 찾고 조회를 STOP합니다. 나온 결과들을 v_sys_instruction 정의된 내용과 v_message,v_user_question 등을 합하여 v_prompt 만들어 dbms_vector_chain.utl_to_generate_text 통해 LLM 질의를 합니다.

CREATE OR REPLACE FUNCTION DRE.fn_rag_test(p_user_question VARCHAR2) RETURN CLOB  
AUTHID DEFINER
IS
  v_model_params JSON ;
  v_user_question_vec vector; 
  v_prompt varchar2(1000);  
  v_sys_instruction varchar2(1000);
  v_message clob; 
  v_user_question varchar2(1000); 
  v_k_stop_count number := 1;
  output clob;
  
BEGIN
  v_model_params := JSON('
    {
    "provider":"OpenAI",
    "credential_name":"EXAONE_CRED",
    "url": "http://172.17.12.116:9301/v1/chat/completions",
    "model": "exaone3.0:8b",
    "context_length" : 2048
    }') ;
  -- JSON형식에서 질의내용만 추출 :
  v_sys_instruction := 'Please answer with only facts based on the searched content.답변은 한국어로 번역해서 대답해줘';
  v_user_question   := p_user_question ;

  -- 질의내용에 대한 쿼리 벡터 생성
    SELECT TO_VECTOR(vector_embedding(onn.distiluse_base_multilingual_cased_v2 USING v_user_question as data)) as embedding into  v_user_question_vec ;  

           
  -- 텍스트 유사도 검색 (Multi-Vector Similarity Search)

select json_arrayagg(
         json_object('EMBED_ID' is EMBED_ID, 'EMBED_DATA' is EMBED_DATA) 
         returning CLOB) into v_message
from (
  SELECT EMBED_ID ,
       EMBED_DATA
  FROM DRE.rag_test
 ORDER BY VECTOR_DISTANCE(EMBED_VECTOR , v_user_question_vec, COSINE) 
 FETCH FIRST v_k_stop_count ROWS ONLY WITH TARGET ACCURACY 90
 );



  -- 프롬프트생성
  v_prompt := ' 
<s>[INST] {system_instruction}.

Search Data:
{insert_search_data_here}

User Query:
{user_query}

Provide a detailed response based on the search data above. [/INST]
  ';

  v_prompt := replace(replace(replace(v_prompt,'system_instruction',v_sys_instruction),'{insert_search_data_here}', v_message),'{user_query}',v_user_question);

  -- Return the substring of the CLOB within the size limit
  --  output := DBMS_LOB.SUBSTR(v_prompt, 4000, 1);
  utl_http.set_body_charset('UTF-8'); 
output := dbms_vector_chain.utl_to_generate_text(v_prompt, v_model_params);
  RETURN output;
END;
/

 

7. RAG 실행

위에서 만들 RAG 함수를 사용하여 Ollama 서버에 증강검색을 합니다. 

DECLARE
  p_user_question  CLOB := '마약류관리에관한법률위반(향정) 를 파기환송한 이유에 대해 알려줘';  -- 여기에 p_user_question의 값을 직접 입력
  output CLOB;
BEGIN
  output := DRE.fn_rag_test(p_user_question );
  DBMS_OUTPUT.PUT_LINE('Output: ' || output);
END;
/
-------------------------[Start Time: 2024/09/12 07:46:11]-------------------------
SQL> Output: 마약류관리에 관한 법률 위반(향정) 사건을 파기환송한 이유는 피고인 및 그와 공범관계에 있던 A의 사례로 볼 수 있습니다. 주된 쟁점은 검사 또는 사법경찰관 작성 피의자신문조서의 증거능력이었습니다.

아래는 이를 근거로 한 상세 설명입니다:

1. **검사 또는 사법경찰관 작성 피의자신문조서**: 피고인과 공범인 A에 대한 경우, 이들 작성한 신문조서가 법적으로 증거 능력을 가지는지 여부가 중요한 쟁점으로 다뤄졌습니다.
   
2. ***형사소송법 제312조***: 형사소송법 제312조는 검사 또는 경찰 작성의 피의자신문조서에 대한 규정을 담고 있으며, 이를 통하여 피고인이 진술거부권과 변호인 조력을 받을 권리를 보호하면서도 실질적인 진술 내용이 신뢰할 만한지 평가합니다.
   - 동 조항에 따르면 피의자나 피고인이 경찰이나 검찰 조사 과정에서 자백하거나 진술한 내용이 진정한 것인지를 판단하기 위해 몇 가지 요건들(예: 피고인의 자발성, 임의성)을 충족해야 합니다.

3. **원심 판결**: 원심(아래 단계 법원)은 이러한 형사 소송법 규정과 그 해석에 따라 본 사건에서 검사 또는 사법경찰관 작성 피의자신문조서를 적법하게 인정하고 유죄판결을 내렸습니다. 그러나 위에서 언급된 요건들이 충분히 충족되지 않았다고 판단하여 사후 증거능력이 문제가 되었고 이에 대한 상고가 제기됐습니다.
   
4. **대법원 판결**: 대법원은 원심의 판단이 부족함을 지적하며 사건을 상급심으로 돌려보냈습니다(즉, 파기환송). 대법원은 보다 면밀한 검토를 통해 실제 조사 과정에서 진술 강요 여부와 자발성 등에 대해 엄격히 재검토할 필요성이 있다고 보았던 것입니다.
   - 또한, 구체적인 사실관계 분석 및 관련 법령 적용에 있어서 추가 조사가 요구된 상황이었기 때문으로 추정됩니다.
 
따라서, 마약류관리에 관한 법률위반(향정)을 기소한 본 사건에서는 법원들 간 해석 차이와 이에 따른 심리 부족 등의 문제로 인해 최종 판단은 상급심인 대법원의 재검토 아래 다시 진행되게 된 것입니다.

 

마치며

테스트를 하면서  신기하다는 느낌은 받았지만, RAG를 활용하여 제품을 만들어서 활용하는 모습은 시간이 조금 걸릴것 같다라는 생각을 했습니다. 하지만, AI기술의 발전 속도를 보면 머지않아 우리 실생활에 빠질 수 없는 중요한 요소가 될 것이라고 생각이 듭니다.

ORACLE DB에서 AI를 활용하여 무엇을 할 수 있다는게 신기했습니다. 제가 테스트한 ORACLE 23AI FREE버전은 23.5인데 dbms_vector_chain.utl_to_generate_text 라는 함수를 사용하여 LLM쪽으로 질의를 하였습니다. 문제는 dbms_vector_chain.utl_to_generate_text 이 함수가 처음에는 VARCHAR2(4000)의 제한이 있었는데 현재 벡터서치 가이드에서는 CLOB로 변경된 것으로 보입니다. 
가이드에서처럼 Ollama Provider제공과 위 함수의 clob 지원이 되는 새로운 버전이 빨리 나왔으면 하는 바램입니다.

'ORACLE 23ai' 카테고리의 다른 글

Oracle Vector Index1-HNSW  (2) 2024.09.19
Oracle Embedding Model Load  (1) 2024.09.05
Embedding  (1) 2024.08.28
RAG(검색 증강 생성)이란  (0) 2024.08.26

+ Recent posts