반응형
Oracle Ai Vector 개념
벡터 하나를 '설문지 응답'이라고 생각해보면 세 가지 저장 방식의 차이있음
- Dense (밀집) 벡터
- 문항 100개짜리 설문지에서 응답자가 모든 문항에 빠짐없이 답한 경우
- 답이 0이어도 그 자리에 0이 물리적으로 저장
- 텍스트 임베딩이 바로 이 형태임
- Sparse (희소) 벡터
- 문항 10000개짜리 설문지인데 응답자가 어차피 대부분 "해당 없음"이라서 답한 문항 몇 개만 기록하는 경우
- '3번 문항=7점, 158번 문항=2점'처럼 (위치, 값) 쌍만 저장하니 공간이 훨씬 절약
- 키워드 검색(BM25, TF-IDF류)에서 주로 사용
- Binary (이진) 벡터
- 문항 하나하나가 그냥 'Yes/No(0/1)'인 체크리스트
- 숫자 하나에 8개 문항(비트)을 사용하여 저장공간이 극도로 작고, 비교 연산(해밍 거리)도 매우빠름
- 그러나 정밀도는 가장 낮으며 정확도보다 일단 후보를 확 걸러내는 1차 필터링 용도로 사용
[oracle@rhel10nm ~]$ id
uid=5001(oracle) gid=500(dba) groups=500(dba) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[oracle@rhel10nm ~]$ env | grep SID
ORACLE_SID=CDB1
[oracle@rhel10nm ~]$
[oracle@rhel10nm ~]$ sqlplus "/as sysdba"
SQL> show con_name
CON_NAME
------------------------------
CDB$ROOT
SQL>
SQL> --PDB1 접속
SQL> ALTER SESSION SET CONTAINER = PDB1;
Session altered.
SQL> --PDB1 접속 확인
SQL> show con_name
CON_NAME
------------------------------
PDB1
SQL>
SQL> --Dense vector
SQL> --DROP TABLE vec_lab_dense PURGE;
SQL> CREATE TABLE vec_lab_dense (
2 id NUMBER,
3 v32 VECTOR(3, FLOAT32), -- 32bit float: 실제 임베딩 모델이 가장 흔히 쓰는 포맷
4 v64 VECTOR(3, FLOAT64), -- 64bit float: 정밀도,저장공간 2배
5 v8 VECTOR(3, INT8) -- 8bit 정수: 저장공간 최소, 정밀도 최저
6 );
Table created.
SQL> desc vec_lab_dense
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NUMBER
V32 VECTOR(3, FLOAT32, DENSE)
V64 VECTOR(3, FLOAT64, DENSE)
V8 VECTOR(3, INT8, DENSE)
SQL>
SQL> INSERT INTO vec_lab_dense
2 VALUES (1, '[1.625, 1.5, 1.0]', '[11.25, 11.75, 11.5]', '[10, 20, 30]');
1 row created.
SQL> commit;
Commit complete.
SQL> set linesize 120
SQL> col V32 for a30
SQL> col V64 for a40
SQL> col v8 for a30
SQL> --입력한 세 벡터가 그대로 조회돼야 함
SQL> SELECT * FROM vec_lab_dense;
ID V32 V64 V8
---------- ------------------------------ ---------------------------------------- ------------------------------
1 [1.625E+000,1.5E+000,1.0E+000] [1.125E+001,1.175E+001,1.15E+001] [10,20,30]
SQL>
SQL> --1.625E+000은 1.625를 지수 표기법(E+000 = ×10⁰ = ×1)
SQL> --입력:[11.25, 11.75, 11.5] -> 출력:[1.125E+001, 1.175E+001, 1.15E+001] (11.25 = 1.125×10¹)
SQL>
SQL> -- Sparse vector
SQL> -- DROP TABLE vec_lab_sparse PURGE;
SQL>
SQL> CREATE TABLE vec_lab_sparse (
2 id NUMBER,
3 v_sp VECTOR(25, FLOAT32, SPARSE)
4 );
Table created.
SQL>
SQL> desc vec_lab_sparse
Name Null? Type
----------------------------------------------------------------- -------- --------------------------------------------
ID NUMBER
V_SP VECTOR(25, FLOAT32, SPARSE)
SQL>
SQL> -- 전체 25차원 중 5, 8, 11번 위치에만 값이 있고 나머지 22개는 0
SQL> INSERT INTO vec_lab_sparse VALUES (1, '[25,[5,8,11],[25.25,6.125,8.25]]');
1 row created.
SQL> commit;
Commit complete.
SQL>
SQL> col V_SP for a50
SQL> SELECT id, v_sp FROM vec_lab_sparse;
ID V_SP
---------- --------------------------------------------------
1 [25,[5,8,11],[2.525E+001,6.125E+000,8.25E+000]]
SQL> -- SELECT결과는 압축된 [25,[5,8,11],[25.25,6.125,8.25]] 형식으로 출력 되어야 함
SQL>
SQL> -- TO_VECTOR로 Dense 변환하여 25개 값을 확인
SQL> set linesize 120
SQL> col V_SP_AS_DENSE for a80
SQL> SELECT id, TO_VECTOR(v_sp, 25, FLOAT32, DENSE) AS v_sp_as_dense FROM vec_lab_sparse;
ID V_SP_AS_DENSE
---------- --------------------------------------------------------------------------------
1 [0,0,0,0,0,2.525E+001,0,0,6.125E+000,0,0,8.25E+000,0,0,0,0,0,0,
SQL> --SELECT결과는 25개 숫자가 다 출력되어야 하며 5, 8, 11번째 자리만 값이 있고 나머지는 0이어야 함
SQL> --위 2개의 Select 결과는 압축 형태와 실제 내용이 같은 데이터의 두 가지 표현 차이
SQL>
SQL> -- Binary vector
SQL> -- DROP TABLE vec_lab_binary PURGE;
SQL>
SQL> CREATE TABLE vec_lab_binary (
2 id NUMBER,
3 v_bin VECTOR(16, BINARY) -- 16차원 = 2바이트
4 );
Table created.
SQL>
SQL> desc vec_lab_binary
Name Null? Type
----------------------------------------------------------------- -------- --------------------------------------------
ID NUMBER
V_BIN VECTOR(16, BINARY, DENSE)
SQL>
SQL> -- 201 = 이진수 11001001, 15 = 이진수 00001111
SQL> -- 이 두 바이트가 합쳐져서 16개의 개별 비트(차원)를 표현함
SQL> INSERT INTO vec_lab_binary VALUES (1, '[201, 15]');
1 row created.
SQL> commit;
Commit complete.
SQL> col V_BIN for a50
SQL> SELECT id, v_bin FROM vec_lab_binary;
ID V_BIN
---------- --------------------------------------------------
1 [201,15]
SQL>
SQL> -- 실습용 Sample Table 생성(문서 1000건 벡터 대량 적재)
SQL> -- lab_documents: a small "document + vector" table.
SQL> -- DROP TABLE lab_documents PURGE;
SQL>
SQL> CREATE TABLE lab_documents (
2 doc_id NUMBER,
3 doc_title VARCHAR2(100),
4 embedding VECTOR(8, FLOAT32)
5 );
Table created.
SQL>
SQL> desc lab_documents
Name Null? Type
----------------------------------------------------------------- -------- --------------------------------------------
DOC_ID NUMBER
DOC_TITLE VARCHAR2(100)
EMBEDDING VECTOR(8, FLOAT32, DENSE)
SQL>
SQL> INSERT INTO lab_documents (doc_id, doc_title, embedding)
2 SELECT
3 LEVEL,
4 'Document ' || LEVEL,
5 TO_VECTOR(
6 '[' ||
7 ROUND(DBMS_RANDOM.VALUE(0,1),3) || ',' ||
8 ROUND(DBMS_RANDOM.VALUE(0,1),3) || ',' ||
9 ROUND(DBMS_RANDOM.VALUE(0,1),3) || ',' ||
10 ROUND(DBMS_RANDOM.VALUE(0,1),3) || ',' ||
11 ROUND(DBMS_RANDOM.VALUE(0,1),3) || ',' ||
12 ROUND(DBMS_RANDOM.VALUE(0,1),3) || ',' ||
13 ROUND(DBMS_RANDOM.VALUE(0,1),3) || ',' ||
14 ROUND(DBMS_RANDOM.VALUE(0,1),3) ||
15 ']'
16 )
17 FROM dual
18 CONNECT BY LEVEL <= 1000;
1000 rows created.
SQL> commit;
Commit complete.
SQL>
SQL> -- 전체 1000건 확인
SQL> SELECT COUNT(*) AS row_count FROM lab_documents;
ROW_COUNT
----------
1000
SQL>
SQL> -- 샘플 3건 확인 - 8개 숫자가 채워진 벡터가 보여야 함
SQL> col EMBEDDING for a80
SQL> col DOC_TITLE for a15
SQL> SELECT doc_id, doc_title, embedding FROM lab_documents WHERE doc_id <= 3;
DOC_ID DOC_TITLE EMBEDDING
---------- --------------- --------------------------------------------------------------------------------
1 Document 1 [5.42999983E-001,3.81999999E-001,9.3900001E-001,6.14000022E-001,
2 Document 2 [5.66999972E-001,9.60000008E-002,3.2100001E-001,6.74000025E-001,
3 Document 3 [7.9400003E-001,3.31E-001,4.79999989E-001,2.56000012E-001,7.54999995E-001,
SQL> --ROW_COUNT가 1000, 샘플 조회에서 각 행마다 8개 실수로 채워진 벡터가 보이면 성공
SQL> exit
Disconnected from Oracle AI Database 26ai Enterprise Edition Release 23.26.2.0.0 - Production
Version 23.26.2.0.0
[oracle@rhel10nm ~]$
반응형
