> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coreweave.com/llms.txt
> Use this file to discover all available pages before exploring further.

# W&B Models와 함께 Weave 사용하기

> W&B Models의 실험 추적과 Weave의 LLM 트레이스 및 평가를 함께 살펴보는 대화형 노트북입니다.

이 노트북에서는 W\&B Models와 Weave를 결합하여 검색 증강 생성(RAG) 애플리케이션을 구축, 평가, 게시하는 엔드투엔드 워크플로를 살펴봅니다. 레지스트리에서 파인튜닝된 채팅 모델을 가져와 Weave에서 추적 중인 기존 `RagModel`의 모델을 교체하고, `weave.Evaluation`으로 업데이트된 애플리케이션을 평가한 다음, 새 RAG 모델을 다시 레지스트리에 게시합니다. 이 워크플로는 W\&B Models로 모델을 학습 및 파인튜닝하고, 이 모델을 Weave로 추적 및 평가하는 LLM 애플리케이션에 통합하려는 팀을 위한 것입니다.

<Note>
  이 노트북은 대화형 노트북입니다. 로컬에서 실행하거나 다음 링크를 사용하세요.

  * [Google Colab에서 열기](https://colab.research.google.com/github/wandb/docs/blob/main/weave/cookbooks/source/Models_and_Weave_Integration_Demo.ipynb)
  * [GitHub에서 소스 보기](https://github.com/wandb/docs/blob/main/weave/cookbooks/source/Models_and_Weave_Integration_Demo.ipynb)
</Note>

<h2 id="prerequisites">
  사전 요구 사항
</h2>

먼저 필요한 라이브러리를 설치하고 API 키를 설정한 다음, Forge에 로그인하여 새 Weights & Biases 프로젝트를 생성하세요.

1. `pip`를 사용하여 `weave`, `pandas`, `unsloth`, `wandb`, `litellm`, `pydantic`, `torch`, `faiss-gpu`를 설치하세요.

```python lines theme={"system"}
%%capture
!pip install weave wandb pandas pydantic litellm faiss-gpu
python
%%capture
!pip install unsloth
# 최신 나이틀리 버전의 Unsloth도 함께 설치합니다!
!pip uninstall unsloth -y && pip install --upgrade --no-cache-dir "unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git"
```

2. 환경에 있는 필수 API 키를 추가하세요.

```python lines theme={"system"}
import os

from google.colab import userdata

os.environ["WANDB_API_KEY"] = userdata.get("WANDB_API_KEY")  # W&B Models 및 Weave
os.environ["OPENAI_API_KEY"] = userdata.get(
    "OPENAI_API_KEY"
)  # OpenAI - 검색용 임베딩에 사용
os.environ["GEMINI_API_KEY"] = userdata.get(
    "GEMINI_API_KEY"
)  # Gemini - 기본 채팅 모델로 사용
```

3. Forge에 로그인한 후 새 프로젝트를 생성하세요.

```python lines theme={"system"}
import pandas as pd
import wandb

import weave

wandb.login()

PROJECT = "weave-cookboook-demo"
ENTITY = "wandb-smle"

weave.init(ENTITY + "/" + PROJECT)
```

<h2 id="download-chatmodel-from-registry-and-implement-unslothlorachatmodel">
  레지스트리에서 `ChatModel`을 다운로드하고 `UnslothLoRAChatModel` 구현하기
</h2>

이 시나리오에서는 Model Team이 성능 최적화를 위해 `unsloth` 라이브러리로 Llama-3.2 모델을 이미 파인튜닝했으며, 해당 모델은 W\&B 레지스트리에서 사용할 수 있습니다. 이 단계에서는 레지스트리에서 파인튜닝된 [`ChatModel`](https://forge.coreweave.com/wandb/wandb-smle/weave-cookboook-demo/weave/object-versions?filter=%7B%22objectName%22%3A%22RagModel%22%7D\&peekPath=%2Fwandb-smle%2Fweave-rag-experiments%2Fobjects%2FChatModelRag%2Fversions%2F2mhdPb667uoFlXStXtZ0MuYoxPaiAXj3KyLS1kYRi84%3F%26)을 가져온 다음, [`RagModel`](https://forge.coreweave.com/wandb/wandb-smle/weave-cookboook-demo/weave/object-versions?filter=%7B%22objectName%22%3A%22RagModel%22%7D\&peekPath=%2Fwandb-smle%2Fweave-cookboook-demo%2Fobjects%2FRagModel%2Fversions%2FcqRaGKcxutBWXyM0fCGTR1Yk2mISLsNari4wlGTwERo%3F%26)과 호환되도록 `weave.Model`로 변환합니다.

<Note>
  다음 코드에서 참조하는 `RagModel`은 하나의 완전한 RAG 애플리케이션으로 볼 수 있는 최상위 `weave.Model`입니다. 여기에는 `ChatModel`, 벡터 데이터베이스, 프롬프트가 포함되어 있습니다. `ChatModel` 역시 `weave.Model`이며, W\&B 레지스트리에서 아티팩트를 다운로드하는 코드가 들어 있습니다. `ChatModel`은 모듈 방식으로 교체할 수 있으므로 `RagModel`의 구성 요소로 다른 종류의 LLM 채팅 모델도 사용할 수 있습니다. 자세한 내용은 [Weave에서 모델 보기](https://forge.coreweave.com/wandb/wandb-smle/weave-cookboook-demo/weave/evaluations?peekPath=%2Fwandb-smle%2Fweave-cookboook-demo%2Fobjects%2FRagModel%2Fversions%2Fx7MzcgHDrGXYHHDQ9BA8N89qDwcGkdSdpxH30ubm8ZM%3F%26)를 참조하세요.
</Note>

`ChatModel`을 로드할 때는 어댑터와 함께 `unsloth.FastLanguageModel` 또는 `peft.AutoPeftModelForCausalLM`을 사용하면 앱에 효율적으로 인테그레이션할 수 있습니다. 레지스트리에서 모델을 다운로드한 후에는 `model_post_init` 메서드로 초기화 및 예측 로직을 설정하세요. 이 단계에 필요한 코드는 레지스트리의 **Use** 탭에서 확인할 수 있으며, 그대로 복사해 구현에 사용할 수 있습니다.

다음 코드는 레지스트리에서 가져온 파인튜닝된 Llama-3.2 모델을 관리, 초기화, 사용하기 위한 `UnslothLoRAChatModel` 클래스를 정의합니다. `UnslothLoRAChatModel`은 최적화된 추론을 위해 `unsloth.FastLanguageModel`을 사용합니다. `model_post_init` 메서드는 모델을 다운로드하고 설정하며, `predict` 메서드는 사용자 쿼리를 처리하고 응답을 생성합니다. 사용 사례에 맞게 코드를 수정하려면 `MODEL_REG_URL`을 파인튜닝된 모델의 올바른 레지스트리 경로로 변경하고, 하드웨어나 요구 사항에 따라 `max_seq_length`, `dtype` 등의 매개변수를 조정하세요.

```python lines theme={"system"}
from typing import Any

from pydantic import PrivateAttr
from unsloth import FastLanguageModel

import weave

class UnslothLoRAChatModel(weave.Model):
    """
    We define an extra ChatModel class to be able store and version more parameters than just the model name.
    Especially, relevant if we consider fine-tuning (locally or aaS) because of specific parameters.
    """

    chat_model: str
    cm_temperature: float
    cm_max_new_tokens: int
    cm_quantize: bool
    inference_batch_size: int
    dtype: Any
    device: str
    _model: Any = PrivateAttr()
    _tokenizer: Any = PrivateAttr()

    def model_post_init(self, __context):
        # 레지스트리의 "Use" 탭에서 이 코드를 복사해 그대로 붙여넣으면 됩니다
        run = wandb.init(project=PROJECT, job_type="model_download")
        artifact = run.use_artifact(f"{self.chat_model}")
        model_path = artifact.download()

        # unsloth 버전 (네이티브로 2배 더 빠른 추론 지원)
        self._model, self._tokenizer = FastLanguageModel.from_pretrained(
            model_name=model_path,
            max_seq_length=self.cm_max_new_tokens,
            dtype=self.dtype,
            load_in_4bit=self.cm_quantize,
        )
        FastLanguageModel.for_inference(self._model)

    @weave.op()
    async def predict(self, query: list[str]) -> dict:
        # add_generation_prompt = true - 생성 시 반드시 추가해야 합니다
        input_ids = self._tokenizer.apply_chat_template(
            query,
            tokenize=True,
            add_generation_prompt=True,
            return_tensors="pt",
        ).to("cuda")

        output_ids = self._model.generate(
            input_ids=input_ids,
            max_new_tokens=64,
            use_cache=True,
            temperature=1.5,
            min_p=0.1,
        )

        decoded_outputs = self._tokenizer.batch_decode(
            output_ids[0][input_ids.shape[1] :], skip_special_tokens=True
        )

        return "".join(decoded_outputs).strip()
python
MODEL_REG_URL = "wandb32/wandb-registry-RAG Chat Models/Finetuned Llama-3.2:v3"

max_seq_length = 2048  # 원하는 값으로 설정하세요! RoPE Scaling은 내부적으로 자동 지원됩니다!
dtype = (
    None  # None은 자동 감지, Tesla T4 및 V100은 Float16, Ampere 이상은 Bfloat16
)
load_in_4bit = True  # 4비트 양자화를 사용해 메모리 사용량을 줄입니다. False로 설정할 수도 있습니다.

new_chat_model = UnslothLoRAChatModel(
    name="UnslothLoRAChatModelRag",
    chat_model=MODEL_REG_URL,
    cm_temperature=1.0,
    cm_max_new_tokens=max_seq_length,
    cm_quantize=load_in_4bit,
    inference_batch_size=max_seq_length,
    dtype=dtype,
    device="auto",
)
python
await new_chat_model.predict(
    [{"role": "user", "content": "What is the capital of Germany?"}]
)
```

<h2 id="integrate-the-new-chatmodel-version-into-ragmodel">
  새 `ChatModel` 버전을 `RagModel`에 통합하기
</h2>

파인튜닝된 채팅 모델로 RAG 애플리케이션을 구축하면 전체 파이프라인을 처음부터 다시 만들지 않고도 맞춤화된 컴포넌트를 재사용할 수 있습니다. 이 단계에서는 Weave 프로젝트에서 기존 `RagModel`을 가져온 다음, 파인튜닝된 모델을 사용하도록 `ChatModel`을 업데이트합니다. 채팅 모델만 새것으로 교체하므로 벡터 데이터베이스나 프롬프트 같은 다른 컴포넌트는 그대로 유지됩니다. 따라서 애플리케이션의 전체 구조를 유지하면서 성능을 높일 수 있습니다.

다음 코드는 Weave 프로젝트의 레퍼런스를 사용해 `RagModel` 객체를 가져옵니다. 그런 다음 이전 단계에서 생성한 새 `UnslothLoRAChatModel` 인스턴스를 사용하도록 `RagModel`의 `chat_model` 속성을 업데이트합니다. 이어서 업데이트된 `RagModel`을 게시하여 새 버전을 생성합니다. 마지막으로 업데이트된 `RagModel`로 샘플 예측 쿼리를 실행하여 새 채팅 모델이 사용되는지 확인합니다.

```python lines theme={"system"}
RagModel = weave.ref(
    "weave://wandb-smle/weave-cookboook-demo/object/RagModel:cqRaGKcxutBWXyM0fCGTR1Yk2mISLsNari4wlGTwERo"
).get()
python
RagModel.chat_model.chat_model
python
await RagModel.predict("When was the first conference on climate change?")
python
# MAGIC: chat_model을 교체하고 새 버전을 게시합니다(다른 RAG 컴포넌트는 신경 쓰지 않아도 됩니다)
RagModel.chat_model = new_chat_model
python
RagModel.chat_model.chat_model
python
# 예측할 때 새 버전을 참조하도록 먼저 새 버전을 게시합니다
PUB_REFERENCE = weave.publish(RagModel, "RagModel")
python
await RagModel.predict("When was the first conference on climate change?")
```

<h2 id="run-a-weaveevaluation">
  `weave.Evaluation` 실행하기
</h2>

업데이트된 `RagModel`을 게시했다면, 다음 단계는 새로 파인튜닝한 채팅 모델이 애플리케이션 안에서 예상대로 동작하는지 확인하는 것입니다. 이 단계에서는 기존 `weave.Evaluation`을 사용해 업데이트된 `RagModel`의 성능을 평가합니다. 이 과정을 통해 새로 파인튜닝한 채팅 모델이 RAG 애플리케이션 안에서 예상대로 동작하는지 확인할 수 있습니다. 인테그레이션을 간소화하고 Models 팀과 Apps 팀이 원활하게 협업할 수 있도록, 평가 결과를 모델의 W\&B run과 Weave 워크스페이스 모두에 로깅합니다.

Models에서:

* 평가 요약은 파인튜닝된 채팅 모델을 다운로드할 때 사용한 W\&B run에 로깅됩니다. 여기에는 분석용으로 [워크스페이스 뷰](https://forge.coreweave.com/wandb/wandb-smle/weave-cookboook-demo/workspace?nw=eglm8z7o9)에 표시되는 summary 메트릭과 그래프가 포함됩니다.
* 평가 트레이스 ID가 run의 설정에 추가되어 Weave 페이지로 바로 연결되므로, Model Team이 더 쉽게 추적할 수 있습니다.

Weave에서:

* `ChatModel`의 아티팩트 또는 레지스트리 링크가 `RagModel`의 입력으로 저장됩니다.
* 컨텍스트를 보강하기 위해 W\&B run ID가 평가 트레이스에 추가 열로 저장됩니다.

다음 코드는 평가 객체를 가져오고, 업데이트된 `RagModel`로 평가를 실행한 뒤, 결과를 W\&B와 Weave 모두에 로깅하는 방법을 보여줍니다. 평가 레퍼런스(`WEAVE_EVAL`)가 프로젝트 설정과 일치하는지 확인하세요.

```python lines theme={"system"}
# MAGIC: 평가 데이터셋과 Scorer가 포함된 평가를 간단히 조회해 바로 사용할 수 있습니다
WEAVE_EVAL = "weave://wandb-smle/weave-cookboook-demo/object/climate_rag_eval:ntRX6qn3Tx6w3UEVZXdhIh1BWGh7uXcQpOQnIuvnSgo"
climate_rag_eval = weave.ref(WEAVE_EVAL).get()
python
with weave.attributes({"wandb-run-id": wandb.run.id}):
    # .call 속성을 사용해 결과와 call을 함께 가져온 뒤, 평가 트레이스를 Models에 저장합니다
    summary, call = await climate_rag_eval.evaluate.call(climate_rag_eval, RagModel)
python
# Models에 로깅
wandb.run.log(pd.json_normalize(summary, sep="/").to_dict(orient="records")[0])
wandb.run.config.update(
    {"weave_url": f"https://forge.coreweave.com/wandb/wandb-smle/weave-cookboook-demo/r/call/{call.id}"}
)
wandb.run.finish()
```

<h2 id="save-the-new-rag-model-to-the-registry">
  새 RAG 모델을 레지스트리에 저장하기
</h2>

업데이트된 `RagModel`의 평가를 마쳤다면, 마지막으로 이 모델을 레지스트리에 다시 게시하여 다른 팀이 찾아서 재사용할 수 있도록 합니다. Models 팀과 Apps 팀 모두 업데이트된 `RagModel`을 앞으로 사용할 수 있도록 참조 아티팩트로 레지스트리에 푸시하세요.

다음 코드는 업데이트된 `RagModel`의 `weave` 객체 버전과 이름을 조회한 뒤, 이를 사용해 참조 링크를 생성합니다. 이어서 모델의 Weave URL을 메타데이터에 담은 새 아티팩트를 W\&B에 생성합니다. 그런 다음 이 아티팩트를 레지스트리에 로깅하고 지정된 레지스트리 경로에 연결합니다.

코드를 실행하기 전에 `ENTITY` 및 `PROJECT` 변수가 W\&B 설정과 일치하는지 확인하고, 올바른 대상 레지스트리 경로를 지정하세요. 이 과정에서 새 `RagModel`을 W\&B 에코시스템에 게시하여 협업과 재사용이 가능해지면 워크플로가 마무리됩니다.

이 섹션의 코드를 실행하면 업데이트된 `RagModel`을 레지스트리에서 참조 아티팩트로 사용할 수 있으며, 이로써 W\&B Models와 Weave 사이의 왕복 과정이 완료됩니다.

```python lines theme={"system"}
MODELS_OBJECT_VERSION = PUB_REFERENCE.digest  # weave 오브젝트 버전
MODELS_OBJECT_NAME = PUB_REFERENCE.name  # weave 오브젝트 이름
python
models_url = f"https://wandb.ai/{ENTITY}/{PROJECT}/weave/objects/{MODELS_OBJECT_NAME}/versions/{MODELS_OBJECT_VERSION}"
models_link = (
    f"weave://{ENTITY}/{PROJECT}/object/{MODELS_OBJECT_NAME}:{MODELS_OBJECT_VERSION}"
)

with wandb.init(project=PROJECT, entity=ENTITY) as run:
    # 새 아티팩트 생성
    artifact_model = wandb.Artifact(
        name="RagModel",
        type="model",
        description="Models Link from RagModel in Weave",
        metadata={"url": models_url},
    )
    artifact_model.add_reference(models_link, name="model", checksum=False)

    # 새 아티팩트 로깅
    run.log_artifact(artifact_model, aliases=[MODELS_OBJECT_VERSION])

    # 레지스트리에 연결
    run.link_artifact(
        artifact_model, target_path="wandb32/wandb-registry-RAG Models/RAG Model"
    )
```


## Related topics

- [예시 코드 및 노트북](/ko/products/wandb/examples.md)
