# 03. Penyematan HuggingFace

```python
from dotenv import load_dotenv

load_dotenv()
```

```python
import os
import warnings

warnings.filterwarnings("ignore")
```

## Data sampel

```python
from langchain_core.documents import Document

texts = [
    "Headphone Bluetooth Nirkabel dengan Pembatalan Kebisingan.",
    "Speaker Bluetooth Tahan Air Portabel dengan Baterai 20 jam.",
    "Kursi Kantor Ergonomis dengan Dukungan Lumbar dan Ketinggian yang Dapat Disesuaikan.",
    "TV Smart 4K Ultra HD dengan Layanan Streaming dan Kontrol Suara.",
    "Meja Berdiri Elektrik dengan Tinggi yang Dapat Disetel Memori."
]
```

## Referensi

| Rank | Model                   | Model Size (Million Parameters) | Memory Usage (GB, fp32) | Embedding Dimensions | Max Tokens | Average (56 datasets) | Classification Average (12 datasets) | Clustering Average (11 datasets) | PairClassification Average (3 datasets) | Reranking Average (4 datasets) | Retrieval Average (15 datasets) | STS Average (10 datasets) | Summarization Average (1 dataset) |
| ---- | ----------------------- | ------------------------------- | ----------------------- | -------------------- | ---------- | --------------------- | ------------------------------------ | -------------------------------- | --------------------------------------- | ------------------------------ | ------------------------------- | ------------------------- | --------------------------------- |
| 1    | bge-en-icl              | 7111                            | 26.49                   | 4096                 | 32768      | 71.67                 | 88.95                                | 57.89                            | 88.14                                   | 59.86                          | 62.16                           | 84.24                     | 30.77                             |
| 2    | stella\_en\_1.5B\_v5    | 1543                            | 5.75                    | 8192                 | 131072     | 71.19                 | 87.63                                | 57.69                            | 88.07                                   | 61.21                          | 61.01                           | 84.51                     | 31.49                             |
| 3    | SFR-Embedding-2\_R      | 7111                            | 26.49                   | 4096                 | 32768      | 70.31                 | 89.05                                | 56.17                            | 88.07                                   | 60.14                          | 60.18                           | 81.26                     | 30.71                             |
| 4    | gte-Qwen2-7B-instruct   | 7613                            | 28.36                   | 3584                 | 131072     | 70.24                 | 86.58                                | 56.92                            | 85.79                                   | 61.42                          | 60.25                           | 83.04                     | 31.35                             |
| 5    | stella\_en\_400M\_v5    | 435                             | 1.62                    | 8192                 | 8192       | 70.11                 | 86.67                                | 56.7                             | 87.74                                   | 60.16                          | 58.97                           | 84.22                     | 31.66                             |
| 6    | bge-multilingual-gemma2 | 9242                            | 34.43                   | 3584                 | 8192       | 69.88                 | 88.08                                | 54.65                            | 85.84                                   | 59.72                          | 59.24                           | 83.88                     | 31.2                              |
| 7    | NV-Embed-v1             | 7851                            | 29.25                   | 4096                 | 32768      | 69.32                 | 87.35                                | 52.8                             | 86.91                                   | 60.54                          | 59.36                           | 82.84                     | 31.2                              |
| 8    | voyage-large-2-instruct | -                               | -                       | 1024                 | 16000      | 68.23                 | 81.49                                | 53.35                            | 89.24                                   | 60.09                          | 58.28                           | 84.31                     | 30.84                             |
| 9    | Linq-Embed-Mistral      | 7111                            | 26.49                   | 4096                 | 32768      | 68.17                 | 80.2                                 | 51.42                            | 88.35                                   | 60.29                          | 60.19                           | 84.97                     | 30.98                             |
| 10   | SFR-Embedding-Mistral   | 7111                            | 26.49                   | 4096                 | 32768      | 67.56                 | 78.33                                | 51.67                            | 88.54                                   | 60.64                          | 59                              | 85.05                     | 31.16                             |

* [papan peringkat untuk membandingkan performa pengambilan informasi dari model-model penyematan.](https://www.google.com/url?q=https%3A%2F%2Fhuggingface.co%2Fspaces%2Fmteb%2Fleaderboard)

## HuggingFace Endpoint Embedding

`HuggingFaceEndpointEmbeddings` sangat mirip dengan apa yang dilakukan HuggingFaceEndpoint di LLM, kecuali bahwa ia menggunakan InferenceClient secara internal untuk menghitung embedding.

```python
from langchain_huggingface.embeddings import HuggingFaceEndpointEmbeddings

model_name = "intfloat/multilingual-e5-large-instruct"

hf_embeddings = HuggingFaceEndpointEmbeddings(
    model=model_name,
    task="feature-extraction",
    huggingfacehub_api_token=os.environ["HUGGINGFACEHUB_API_TOKEN"],
)
```

Penyematan dokumen dapat dibuat dengan memanggil `embed_documents()`.

```python
%%time
# Document Embedding 수행
embedded_documents = hf_embeddings.embed_documents(texts)
```

```
Time taken: 1.7642 seconds
```

```python
print("[HuggingFace Endpoint Embedding]")
print(f"Model: \t\t{model_name}")
print(f"Dimension: \t{len(embedded_documents[0])}")
```

```
[HuggingFace Endpoint Embedding]
Model:          intfloat/multilingual-e5-large-instruct
Dimension:      1024
```

```python
# Melakukan Embedding pada Kueri
embedded_query = hf_embeddings.embed_query("Saya membutuhkan produk untuk ruangan kantor saya")
```

## Menghitung kemiripan

**Menghitung kemiripan melalui hasil kali dalam vektor** - Menghitung kemiripan menggunakan hasil kali dalam vektor (dot product).

* Rumus untuk menghitung kemiripan:

<figure><img src="https://3432011104-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FMUIRwwCkXCd5fR0xUSJp%2Fuploads%2FjyP0BsKQwQN6sZeqkflH%2Fimage.png?alt=media&#x26;token=4fbe7041-6f20-4618-a9ff-b7d793c6484d" alt=""><figcaption></figcaption></figure>

## Arti Matematis dari Intrinsik Vektor

**Definisi Intrinsik Vektor**

Vektor a dan b didefinisikan sebagai berikut

<figure><img src="https://3432011104-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FMUIRwwCkXCd5fR0xUSJp%2Fuploads%2F3Zd4TZHvB3iBIbCeHO9E%2Fimage.png?alt=media&#x26;token=0250d315-2f5d-4790-bd31-cd0bd2287457" alt=""><figcaption></figcaption></figure>

## **Hubungan dengan Kesamaan Kosinus**

Hasil kali dalam vektor memiliki sifat-sifat berikut

<figure><img src="https://3432011104-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FMUIRwwCkXCd5fR0xUSJp%2Fuploads%2F1sLcSEjoirrMhdN4CF08%2Fimage.png?alt=media&#x26;token=9a096ee1-e9e6-4e9c-827e-b1d5229f4d36" alt=""><figcaption></figcaption></figure>

di mana,

* |a|dan|b| adalah vektor-vektor, a dan b adalah besaran (norma Euclidean)
* θ adalah sudut antara kedua vektor.
* cos θ adalah kesamaan kosinus antara kedua vektor.

\*_Menginterpretasikan kemiripan vektor intrinsik \*_&#x73;ebagai semakin besar nilai intrinsik (semakin besar nilai positif),

* Besarnya dua buah vektor ( |a| dan |b|) adalah besar,
* Besar sudut antara dua buah vektor (θ) kecil dan (cos θ (mendekati 1))

Ini berarti bahwa kedua vektor menunjuk ke arah yang sama, dan semakin besar magnitudo, semakin mirip keduanya.

## Menghitung besaran (norm) sebuah vektor

Vektor definisi norma Euclidean:

<figure><img src="https://3432011104-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FMUIRwwCkXCd5fR0xUSJp%2Fuploads%2FdggHxg7BZwPMUH5l8j2S%2Fimage.png?alt=media&#x26;token=eeef0b05-37ec-4b80-9067-412aa73a3e34" alt=""><figcaption></figcaption></figure>

Tentang, norma Euclidean |a| didefinisikan sebagai berikut:

<figure><img src="https://3432011104-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FMUIRwwCkXCd5fR0xUSJp%2Fuploads%2F0zu5nPs1BxgyKPVkKFCD%2Fimage.png?alt=media&#x26;token=d7d6fa9f-a5f1-4964-8ce8-ecdb9e1e5815" alt=""><figcaption></figcaption></figure>

Hitung kemiripan antara kueri dan embedding\_document

```python
import numpy as np

# Pertanyaan (embedded_query): Saya membutuhkan produk untuk ruangan kantor saya.
np.array(embedded_query) @ np.array(embedded_documents).T
```

```
[0.81501292 0.79971248 0.84330415 0.78584163 0.8327097 ]
```

```python
sorted_idx = (np.array(embedded_query) @ np.array(embedded_documents).T).argsort()[::-1]
sorted_idx
```

```
[2 4 0 1 3]
```

```python
print("[Query] Saya membutuhkan produk untuk ruangan kantor saya.\n====================================")
for i, idx in enumerate(sorted_idx):
    print(f"[{i}] {texts[idx]}")
    print()
```

```
[Query] Saya membutuhkan produk untuk ruangan kantor saya
====================================
[0] Kursi Kantor Ergonomis dengan Dukungan Lumbar dan Ketinggian yang Dapat Disesuaikan.

[1] Meja Berdiri Elektrik dengan Tinggi yang Dapat Disetel Memori.

[2] Headphone Bluetooth Nirkabel dengan Pembatalan Kebisingan.

[3] Speaker Bluetooth Tahan Air Portabel dengan Baterai 20 jam.

[4] TV Smart 4K Ultra HD dengan Layanan Streaming dan Kontrol Suara.
```

## HuggingFace Embeddings

`intfloat/multilingual-e5-large-instruct`

* [intfloat/multilingual-e5-large-instruct](https://www.google.com/url?q=https%3A%2F%2Fhuggingface.co%2Fintfloat%2Fmultilingual-e5-large-instruct)
* [intfloat/multilingual-e5-large](https://www.google.com/url?q=https%3A%2F%2Fhuggingface.co%2Fintfloat%2Fmultilingual-e5-large)

```python
from langchain_huggingface.embeddings import HuggingFaceEmbeddings

model_name = "intfloat/multilingual-e5-large-instruct"
# model_name = "intfloat/multilingual-e5-large"

hf_embeddings = HuggingFaceEmbeddings(
    model_name=model_name,
    model_kwargs={"device": "cuda"},  # cuda, cpu
    encode_kwargs={"normalize_embeddings": True},
)
```

```python
%time
# Document
embedded_documents1 = hf_embeddings.embed_documents(texts)
```

```
Time taken: 1.9415 seconds
```

```python
print(f"Model: \t\t{model_name}")
print(f"Dimension: \t{len(embedded_documents[0])}")
```

```
Model:          intfloat/multilingual-e5-large-instruct
Dimension:      1024
```

```python
from langchain_huggingface import HuggingFaceEmbeddings

model_name = "BAAI/bge-m3"
model_kwargs = {"device": "cuda"}
encode_kwargs = {"normalize_embeddings": True}
hf_embeddings = HuggingFaceEmbeddings(
    model_name=model_name, model_kwargs=model_kwargs, encode_kwargs=encode_kwargs
)
```

```python
%time
# Document
embedded_documents = hf_embeddings.embed_documents(texts)
```

```
Time taken: 1.9415 seconds
```

```python
print(f"Model: \t\t{model_name}")
print(f"Dimension: \t{len(embedded_documents[0])}")
```

```
Model:          BAAI/bge-m3
Dimension:      1024
```

## **Cara menggunakan `FlagEmbedding`**

Referens - [FlagEmbedding - BGE-M3 Usage](https://github.com/FlagOpen/FlagEmbedding/tree/master/FlagEmbedding/BGE_M3#usage)

Dengan menggabungkan tiga pendekatan yang ditawarkan oleh FlagEmbedding, Anda dapat membangun sistem pencarian yang lebih kuat.

Dense Vector: dibangun di atas kemampuan multibahasa dan multitasking BGE-M3 Penyematan jarang dengan bobot leksikal untuk pencocokan kata yang akurat Pendekatan multi-vektor ColBERT untuk pencocokan kontekstual berbutir halus.

```python
# Menginstal FlagEmbedding
!pip install -qU FlagEmbedding
```

```python
from FlagEmbedding import BGEM3FlagModel

model_name = "BAAI/bge-m3"
bge_embeddings = BGEM3FlagModel(
    model_name, use_fp16=True
)  # Mengatur use_fp16 ke True akan mempercepat proses perhitungan dengan sedikit penurunan kinerja.

bge_embedded = bge_embeddings.encode(
    texts,
    batch_size=12,
    max_length=8192,  # Jika panjang sebesar ini tidak diperlukan, Anda dapat mengatur nilai yang lebih kecil untuk mempercepat proses encoding.
)["dense_vecs"]
```

```python
bge_embedded.shape
```

```
(5, 1024)
```

```python
print(f"Model: \t\t{model_name}")
print(f"Dimension: \t{len(embedded_documents[0])}")
```

```
Model:          BAAI/bge-m3
Dimension:      1024
```

```python
from FlagEmbedding import BGEM3FlagModel

bge_flagmodel = BGEM3FlagModel(
    "BAAI/bge-m3", use_fp16=True
)  # Mengatur use_fp16 ke True akan mempercepat proses perhitungan dengan sedikit penurunan kinerja.
bge_encoded = bge_flagmodel.encode(texts, return_dense=True)
```

```python
# Menampilkan hasil (baris, kolom)
bge_encoded["dense_vecs"].shape
```

```
(5, 1024)
```

## Sparse Embdedding (Lexical Weight)

Sparse embedding adalah metode embedding yang menggunakan vektor berdimensi tinggi di mana sebagian besar nilai dalam vektor tersebut adalah nol. Metode bobot leksikal memperhitungkan pentingnya kata-kata untuk membuat penyematan.

**Cara kerjanya** 1. Hitung bobot leksikal untuk setiap kata. Hal ini dapat dilakukan dengan menggunakan metode seperti TF-IDF atau BM25. 2. Untuk setiap kata dalam dokumen atau kueri, tetapkan nilai pada dimensi yang sesuai dari vektor jarang menggunakan bobot leksikal kata tersebut. 3. Hasilnya adalah representasi vektor dimensi tinggi dari dokumen atau kueri dengan sebagian besar nilai adalah nol.

**Keuntungan** - Dapat secara langsung mencerminkan pentingnya sebuah kata. - Dapat secara akurat mencocokkan kata atau frasa tertentu. - Komputasi relatif cepat.

```python
bge_flagmodel = BGEM3FlagModel(
    "BAAI/bge-m3", use_fp16=True
)  # Mengatur use_fp16 ke True akan mempercepat proses perhitungan dengan sedikit penurunan kinerja.
bge_encoded = bge_flagmodel.encode(texts, return_sparse=True)
```

```python
lexical_scores1 = bge_flagmodel.compute_lexical_matching_score(
    bge_encoded["lexical_weights"][0], bge_encoded["lexical_weights"][0]
)
lexical_scores2 = bge_flagmodel.compute_lexical_matching_score(
    bge_encoded["lexical_weights"][0], bge_encoded["lexical_weights"][1]
)
# 0 <-> 0
print(lexical_scores1)
# 0 <-> 1
print(lexical_scores2)
```

```
0.2894423007965088
0.07880592346191406
```

## Multi-Vector (ColBERT)

Contextualised Late Interaction over BERT (ColBERT) adalah metode yang efisien untuk pencarian dokumen. Metode ini menggunakan pendekatan multi-vektor, di mana dokumen dan kueri diwakili oleh beberapa vektor.

**Bagaimana cara kerjanya**

1. Vektor terpisah dibuat untuk setiap token dalam dokumen, yaitu, dokumen diwakili oleh beberapa vektor.
2. Kueri juga membuat vektor terpisah untuk setiap token.
3. Saat mencari, kami menghitung kesamaan antara setiap vektor token dalam kueri dan semua vektor token dalam dokumen.
4. Kemiripan ini digabungkan untuk menghitung skor pencarian akhir.

**Keuntungan** - Pencocokan tingkat token berbutir halus dimungkinkan. - Dapat menghasilkan sematan yang peka terhadap konteks. - Bekerja dengan baik untuk dokumen yang panjang.

```python
bge_flagmodel = BGEM3FlagModel(
    "BAAI/bge-m3", use_fp16=True
)  # Mengatur use_fp16 ke True akan mempercepat proses perhitungan dengan sedikit penurunan kinerja.
bge_encoded = bge_flagmodel.encode(texts, return_colbert_vecs=True)
```

```python
colbert_scores1 = bge_flagmodel.colbert_score(
    bge_encoded["colbert_vecs"][0], bge_encoded["colbert_vecs"][0]
)
colbert_scores2 = bge_flagmodel.colbert_score(
    bge_encoded["colbert_vecs"][0], bge_encoded["colbert_vecs"][1]
)
# 0 <-> 0
print(colbert_scores1)
# 0 <-> 1
print(colbert_scores2)
```

```
tensor(1.)
tensor(0.5276)
```
