본문으로 바로가기

Unsloth로 PubMedQA에서 DiffusionGemma 미세 조정하는 방법

RunPod H100 GPU에서 Unsloth, LoRA, Hugging Face를 사용해 PubMedQA의 생의학 질의응답 작업에 DiffusionGemma 26B-A4B를 미세 조정하는 방법을 알아보세요.
업데이트됨 2026년 8월 3일  · 9분 읽다

AI로 탐색하기

ChatGPT에서 열기Claude에서 열기Perplexity에서 열기

DiffusionGemma는 전통적인 대규모 언어 모델과는 다른 방식으로 텍스트를 생성하는 Google DeepMind의 실험적 언어 모델입니다. 왼쪽에서 오른쪽으로 한 번에 하나의 토큰을 예측하는 대신, 고정된 캔버스에 잡음이 섞인 토큰을 배치한 후 여러 번의 디노이징 단계를 거치며 점차 정제합니다. 이를 통해 모델은 여러 토큰 위치를 병렬로 업데이트하고, 생성 중에 일부 응답을 수정할 수 있습니다.

이 가이드에서는 NVIDIA H100 GPU를 사용해 PubMedQA 데이터셋으로 미세 조정diffusiongemma-26B-A4B-it 모델을 다룹니다. 모델은 생의학 질문과 참고 문맥을 입력으로 받아 yes, no, 또는 maybe를 예측합니다. 데이터를 준비하고, LoRA 어댑터를 학습하며, 미세 조정 전후의 성능을 평가하고, 최종 어댑터를 Hugging Face에 업로드하겠습니다.

원본 코드를 검토하고, 따라 해 보고, 직접 실험을 실행할 수 있도록 완성된 노트북도 공개했습니다.

주의: 이 프로젝트는 학습 및 실험 목적으로만 제공되며 실제 의료 결정에 사용해서는 안 됩니다.

1. RunPod Jupyter 노트북 열기

NVIDIA H100 GPU로 새 RunPod 파드를 생성하고 PyTorch/Jupyter 템플릿을 선택하세요. 파드가 중지되어도 모델 파일과 학습 산출물이 손실되지 않도록 지속 스토리지를 최소 100 GB로 설정합니다.

Hugging Face 액세스 토큰을 환경 변수로 추가합니다:

HF_TOKEN=your_hugging_face_token

Editing the Runpod Pytorch template

이렇게 하면 모델과 데이터셋을 더 빠르게 내려받을 수 있고, 노트북에서 수동으로 로그인하지 않아도 저장된 LoRA 어댑터를 Hugging Face에 업로드할 수 있습니다.

구성한 파드의 비용은 시간당 약 $3이며, 최종 가격은 GPU 가용성과 선택한 파드 유형에 따라 달라질 수 있습니다.

Runpod H100 GPU summary

파드가 실행되면 RunPod 인터페이스에서 JupyterLab 또는 Jupyter Notebook을 열고 diffusiongemma_pubmedqa.ipynb라는 이름의 새 노트북을 만드세요.

2. 필요한 패키지 설치

다음 명령을 노트북의 첫 번째 셀에서 실행하여 Unsloth와 DiffusionGemma를 로드, 미세 조정, 저장하는 데 필요한 라이브러리를 설치합니다.

%%capture
%pip install --upgrade pip wheel setuptools packaging ninja
%pip install unsloth
%pip install --no-deps --upgrade --force-reinstall git+https://github.com/unslothai/unsloth-zoo.git git+https://github.com/unslothai/unsloth.git
%pip install sentencepiece protobuf "datasets==4.3.0" "huggingface_hub>=0.34.0" hf_transfer
%pip install --no-deps bitsandbytes accelerate peft trl triton
%pip install --no-deps --upgrade "torchao>=0.16.0"
%pip install --no-deps transformers==5.11.0 "tokenizers>=0.22.0,<=0.23.0"

%%capture 명령은 긴 설치 출력을 숨깁니다. DiffusionGemma, Transformers, Unsloth, 학습 라이브러리 간의 호환성 문제를 피하기 위해 패키지 버전을 고정했습니다.

설치가 완료되면 계속하기 전에 노트북 커널을 재시작하세요.

3. 라이브러리 임포트

데이터셋 준비, 모델 로딩, 학습, 평가에 필요한 라이브러리를 임포트합니다.

import copy
import os
import random
import time

import torch
from datasets import load_dataset
from unsloth import FastModel

os.environ["HF_HUB_ENABLE_HF_TRANSFER"] = "1"
torch._dynamo.config.recompile_limit = 64

print("Torch:", torch.__version__)
print("CUDA available:", torch.cuda.is_available())
print(
    "GPU:",
    torch.cuda.get_device_name(0)
    if torch.cuda.is_available()
    else "None",
)

HF_HUB_ENABLE_HF_TRANSFER는 Hugging Face Hub에서 더 빠른 다운로드를 활성화하며, Dynamo 재컴파일 한도를 높이면 모델 작업 중 중단을 방지하는 데 도움이 됩니다.

셀 실행이 성공하면 Unsloth가 학습 환경을 패치하고, CUDA 사용 가능 여부와 H100 GPU가 감지되었음을 출력에서 확인할 수 있습니다.

🦥 Unsloth: Will patch your computer to enable 2x faster free fine-tuning.
🦥 Unsloth Zoo will now patch everything to make training faster!
Torch: 2.10.0+cu128
CUDA available: True
GPU: NVIDIA H100 80GB HBM3

4. 설정 정의

한 곳에서 모델, 데이터셋, 학습 파라미터, 평가 설정, 출력 디렉터리를 정의합니다.

MODEL_NAME = "unsloth/diffusiongemma-26B-A4B-it"
DATASET_NAME = "qiaojin/PubMedQA"

TRAIN_SUBSET = "pqa_artificial"
EVAL_SUBSET = "pqa_labeled"

N_TRAIN = 3000
N_EVAL = 200

MAX_CONTEXT_CHARS = 2500

STEPS = 60
GRAD_ACCUM = 4
LR = 1e-4
T_LO = 0.1

EVAL_TOTAL = 50
EVAL_DENOISING_STEPS = 16

OUTPUT_DIR = "diffusiongemma_pubmedqa_lora"

학습에는 3,000개의 인공 예제를, 평가에는 200개의 수작업 라벨 예제를 사용합니다. 실험을 빠르게 진행하기 위해 모델은 60스텝 동안 학습하고, 16번의 디노이징 스텝으로 50개 예제를 평가합니다.

DiffusionGemma 작동 방식

모델을 로드하기 전에, DiffusionGemma가 실제로 어떻게 답을 만들어내는지 그려보는 것이 좋습니다. 이 모델은 토큰을 차례차례 생성하는 대신, 고정 길이 캔버스에 토큰을 배치하고 여러 디노이징 단계를 거치며 동시에 여러 위치를 업데이트해 일관된 응답으로 수렴시킵니다. 

아래 코드는 단일 블록의 크기인 256의 캔버스 길이를 보고합니다. 우리처럼 짧은 yes/no/maybe 답변에는 한 개의 캔버스로 충분하며, 더 긴 출력은 블록 단위로 캔버스를 연쇄해 생성합니다. 아래 다이어그램은 이 정제 과정을 높은 수준에서 보여줍니다:

Text Diffusion Explanation

5. DiffusionGemma 로드

bfloat16 정밀도로 지시 튜닝된 DiffusionGemma 모델을 로드합니다. H100 GPU는 더 높은 정밀도의 모델을 로드할 충분한 메모리를 갖추고 있으므로 4비트 양자화는 사용하지 않습니다.

model, tokenizer = FastModel.from_pretrained(
    model_name=MODEL_NAME,
    dtype=torch.bfloat16,
    load_in_4bit=False,
)

processor = tokenizer
tok = processor.tokenizer if hasattr(processor, "tokenizer") else processor

vocab = model.config.text_config.vocab_size
canvas_len = model.config.canvas_length

dev = next(
    (p.device for p in model.parameters() if p.device.type != "meta"),
    torch.device("cuda"),
)

print("Vocab size:", vocab)
print("Canvas length:", canvas_len)
print("Model device:", dev)

어휘 크기는 확산 학습 중 무작위 잡음을 추가할 때 사용됩니다. 캔버스 길이는 모델이 단일 생성 블록에서 정제할 수 있는 최대 토큰 수를 결정합니다.

다음과 유사한 출력을 보게 됩니다:

Vocab size: 262144
Canvas length: 256
Model device: cuda:0

6. LoRA 어댑터 추가

전체 260억 매개변수를 업데이트하는 대신, 소수의 추가 매개변수만 학습하도록 LoRA 어댑터를 추가합니다.

model = FastModel.get_peft_model(
    model,
    r=64,
    lora_alpha=128,
    use_gradient_checkpointing=False,
)

이렇게 하면 미세 조정에 필요한 메모리와 연산량이 크게 줄어듭니다. 본 실험에서는 H100의 GPU 메모리가 충분하므로 그래디언트 체크포인팅은 비활성화합니다.

7. PubMedQA 로드

학습용 인공 PubMedQA 서브셋과 평가용 수작업 라벨 서브셋을 로드합니다.

train_data = load_dataset(
    DATASET_NAME,
    TRAIN_SUBSET,
    split="train",
)

eval_data = load_dataset(
    DATASET_NAME,
    EVAL_SUBSET,
    split="train",
)

print("Train size:", len(train_data))
print("Eval size:", len(eval_data))
print(train_data[0])

학습 서브셋에는 자동으로 생성된 예제가, 평가 서브셋에는 전문가가 라벨링한 생의학 질문이 포함됩니다. 

첫 번째 행을 출력해 질문, 초록 문맥, 최종 결정을 포맷팅 전에 확인합니다.

다음과 같은 출력을 볼 수 있습니다:

Train size: 211269
Eval size: 1000

각 예제는 생의학 질문, 하나 이상의 지원 초록 문단, 그리고 최종 답변 yes, no, 또는 maybe를 포함합니다.

Loading the PubMedQA

8. 데이터셋 변환

각 PubMedQA 예제를 사용자 프롬프트와 어시스턴트 답변이 포함된 챗 형식으로 변환합니다.

def make_prompt(row):
    context = " ".join(row["context"]["contexts"])
    context = context[:MAX_CONTEXT_CHARS]
    question = row["question"]

    return f"""Answer the biomedical research question using only the context.

Context:
{context}

Question:
{question}

Answer with only one word: yes, no, or maybe."""


def make_answer(row):
    return row["final_decision"].strip().lower()


def convert_row(row):
    answer = make_answer(row)

    if answer not in ["yes", "no", "maybe"]:
        return None

    return {
        "messages": [
            {"role": "user", "content": make_prompt(row)},
            {"role": "assistant", "content": answer},
        ]
    }


train_rows = []

for row in train_data.select(range(N_TRAIN)):
    item = convert_row(row)

    if item is not None:
        train_rows.append(item)


eval_rows = []

for row in eval_data.select(range(N_EVAL)):
    item = convert_row(row)

    if item is not None:
        eval_rows.append(item)


print("Prepared train examples:", len(train_rows))
print("Prepared eval examples:", len(eval_rows))
print(train_rows[0]["messages"][0]["content"])
print("Answer:", train_rows[0]["messages"][1]["content"])

문맥 문단은 하나의 문자열로 결합하고 입력을 과도하게 늘리지 않도록 2,500자로 제한합니다. 각 답변은 소문자로 변환하며, 라벨이 yes, no, maybe 외인 예제는 제거합니다.

첫 번째 변환 예제를 출력해 학습 전에 문맥, 질문, 답변이 올바르게 포맷되었는지 확인합니다.

Formatting the PubMedQA dataset in chat format

9. 확산 학습 예제 생성

DiffusionGemma는 목표 답변을 고정 길이 캔버스에 배치해야 합니다. 이 함수는 프롬프트를 토크나이즈하고, 답변을 토큰 ID로 변환한 뒤 모델의 캔버스 길이에 맞춰 패딩하며, 손실에 기여할 토큰을 표시하는 마스크를 생성합니다.

eos = model.generation_config.eos_token_id or [1]
eos = eos[0] if isinstance(eos, (list, tuple)) else eos

pad = tok.pad_token_id if tok.pad_token_id is not None else eos


def build_examples(rows):
    examples = []

    for row in rows:
        user_message = row["messages"][0]
        assistant_message = row["messages"][1]

        prompt_ids = processor.apply_chat_template(
            [user_message],
            tokenize=True,
            add_generation_prompt=True,
            return_tensors="pt",
        )[0]

        answer_ids = tok.encode(
            assistant_message["content"],
            add_special_tokens=False,
        )

        content = answer_ids + [eos]
        n = len(content)

        if n > canvas_len:
            continue

        x0 = torch.tensor(
            content + [pad] * (canvas_len - n),
            dtype=torch.long,
        )

        loss_mask = torch.zeros(canvas_len, dtype=torch.bool)
        loss_mask[:n] = True

        examples.append((prompt_ids, x0, loss_mask))

    return examples


examples = build_examples(train_rows)

각 답변 뒤에는 시퀀스 종료 토큰을 추가하고, 남은 캔버스 위치는 패딩 토큰으로 채웁니다. 손실 마스크는 패딩 위치가 아닌 실제 답변과 종료 토큰에만 학습이 집중되도록 보장합니다.

10. 추론 및 평가 함수 생성

다음으로, 답변을 생성하고, 모델 출력을 정리하며, 평가 정확도를 계산하는 함수들을 정의합니다.

답변 생성

answer_question() 함수는 프롬프트를 포맷하고, 여러 디노이징 단계를 거쳐 응답을 생성한 뒤 생성된 토큰을 텍스트로 디코딩합니다.

def answer_question(prompt, steps=64):
    input_ids = processor.apply_chat_template(
        [{"role": "user", "content": prompt}],
        tokenize=True,
        add_generation_prompt=True,
        return_tensors="pt",
    ).to(dev)

    gen_config = copy.deepcopy(model.generation_config)
    gen_config.max_denoising_steps = steps
    gen_config.max_new_tokens = canvas_len

    model.eval()

    with torch.no_grad():
        output = model.generate(
            input_ids=input_ids,
            generation_config=gen_config,
        )

    generated = output.sequences[0, input_ids.shape[1]:]
    text = tok.decode(
        generated.tolist(),
        skip_special_tokens=True,
    )

    return text.strip().lower()

예측 추출

프롬프트는 한 단어로 답하도록 요청하지만, 모델이 가끔 추가 텍스트를 생성할 수 있습니다. 이 함수는 첫 번째 유효한 yes, no, 또는 maybe 예측을 추출합니다.

def clean_prediction(text):
    text = text.lower().strip()

    if text.startswith("yes"):
        return "yes"

    if text.startswith("no"):
        return "no"

    if text.startswith("maybe"):
        return "maybe"

    words = text.replace(".", " ").replace(",", " ").split()

    for word in words:
        if word in ["yes", "no", "maybe"]:
            return word

    return "unknown"

정확도 평가

평가 함수는 정리된 각 예측을 정답과 비교하고, 각 예제의 결과를 출력하며, 전체 정확도와 개별 예측을 함께 반환합니다.

def evaluate_model(
    rows,
    total=50,
    steps=64,
    title="Evaluation",
):
    correct = 0
    results = []
    total = min(total, len(rows))

    print(title)
    print("-" * len(title))

    for i, row in enumerate(rows[:total], start=1):
        prompt = row["messages"][0]["content"]
        gold = row["messages"][1]["content"]

        raw_pred = answer_question(prompt, steps=steps)
        pred = clean_prediction(raw_pred)

        is_correct = pred == gold
        correct += int(is_correct)

        results.append({
            "index": i,
            "gold": gold,
            "prediction": pred,
            "raw_prediction": raw_pred,
            "correct": is_correct,
        })

        print(
            f"{i:02d}. Gold: {gold} | "
            f"Pred: {pred} | Correct: {is_correct}"
        )

    accuracy = correct / total if total else 0

    print()
    print("Accuracy:", accuracy)
    print()

    return {
        "accuracy": accuracy,
        "correct": correct,
        "total": total,
        "results": results,
    }

11. 미세 조정 전 모델 평가

학습 전에 평가를 실행해 기준선을 마련합니다.

before_eval = evaluate_model(
    eval_rows,
    total=EVAL_TOTAL,
    steps=EVAL_DENOISING_STEPS,
    title="Before Fine-Tuning Evaluation",
)

각 답변당 16번의 디노이징 스텝으로 50개 예제를 평가합니다. 이 실험에서 기본 모델은 50문항 중 30문항에 정답을 냈습니다.

Baseline result of the DiffusionGemma

이 기준선은 이후 미세 조정 후 모델의 정확도와 비교됩니다.

12. 학습 설정

모델을 학습 모드로 전환하고, 옵티마이저와 학습률 스케줄러를 생성하며, 확산 학습 중 깨끗한 답변 토큰이 어떻게 훼손될지 정의합니다.

model.config.use_cache = True
model.train()

opt = torch.optim.AdamW(
    [p for p in model.parameters() if p.requires_grad],
    lr=LR,
    betas=(0.9, 0.95),
    weight_decay=0.0,
)

sched = torch.optim.lr_scheduler.OneCycleLR(
    opt,
    max_lr=LR,
    total_steps=STEPS,
    pct_start=0.03,
    anneal_strategy="cos",
)

requires_grad=True인 파라미터만 옵티마이저에 전달되므로, 전체 모델이 아니라 LoRA 어댑터만 업데이트됩니다.

다음으로, 답변 캔버스의 임의 비율을 무작위 토큰으로 바꾸는 훼손 함수를 만듭니다.

def corrupt(x0):
    noise_level = random.uniform(T_LO, 1.0)

    xt = x0.to(dev).clone()

    noise_mask = (
        torch.rand(canvas_len, device=dev) < noise_level
    )

    xt[noise_mask] = torch.randint(
        0,
        vocab,
        (canvas_len,),
        device=dev,
    )[noise_mask]

    return xt.unsqueeze(0)

잡음의 양은 예제마다 달라집니다. 학습 중 모델은 이렇게 훼손된 캔버스 토큰으로부터 원래 답변을 복원하는 법을 배웁니다.

13. 모델 학습

다음 루프는 그래디언트 누적을 사용해 60스텝 동안 LoRA 어댑터를 학습합니다.

order = list(range(len(examples)))
ptr = 0
start_time = time.time()

opt.zero_grad(set_to_none=True)

for step in range(1, STEPS + 1):
    step_loss = 0.0

    for _ in range(GRAD_ACCUM):
        if ptr >= len(order):
            random.shuffle(order)
            ptr = 0

        prompt_ids, x0, loss_mask = examples[order[ptr]]
        ptr += 1

        output = model(
            input_ids=prompt_ids.unsqueeze(0).to(dev),
            canvas_ids=corrupt(x0),
            self_conditioning_logits=None,
        )

        logits = output.logits[0].float()
        mask = loss_mask.to(dev)

        loss = torch.nn.functional.cross_entropy(
            logits[mask],
            x0.to(dev)[mask],
        )

        (loss / GRAD_ACCUM).backward()
        step_loss += loss.item() / GRAD_ACCUM

    torch.nn.utils.clip_grad_norm_(
        [
            p
            for p in model.parameters()
            if p.requires_grad
        ],
        1.0,
    )

    opt.step()
    sched.step()
    opt.zero_grad(set_to_none=True)

    if step % 20 == 0:
        elapsed = time.time() - start_time

        print(
            f"step {step}/{STEPS} | "
            f"loss {step_loss:.4f} | "
            f"{elapsed:.0f}s"
        )

각 학습 예제에서 모델은 생의학 프롬프트와 훼손된 답변 캔버스를 입력으로 받습니다. 크로스 엔트로피 손실은 손실 마스크로 선택된 실제 답변 토큰에 대해서만 계산됩니다.

그래디언트 누적은 네 개 예제를 결합한 후 모델을 업데이트합니다. 학습의 안정성을 위해 그래디언트 클리핑도 적용됩니다.

본 실험에서는 약 2분 만에 학습이 완료되었습니다:

step 20/60 | loss 0.0019 | 43s
step 40/60 | loss 0.0003 | 85s
step 60/60 | loss 0.0001 | 126s

손실이 꾸준히 감소하는 것은 어댑터가 훼손된 캔버스에서 기대 답변을 복원하는 법을 학습하고 있음을 나타냅니다. 학습 중 RunPod 터미널에서 nvidia-smi를 실행해 GPU 메모리 사용량과 활용률을 모니터링할 수도 있습니다.

Nvidia model statistic while model training

14. 미세 조정된 모델 평가

학습 후 동일한 평가를 다시 실행해 미세 조정이 모델 성능을 개선했는지 확인합니다.

after_eval = evaluate_model(
    eval_rows,
    total=EVAL_TOTAL,
    steps=EVAL_DENOISING_STEPS,
    title="After Fine-Tuning Evaluation",
)

미세 조정된 모델은 기준선 평가와 동일하게 50개 예제, 16번의 디노이징 스텝으로 평가됩니다.

Fine-tune result of the DiffusionGemma

이제 미세 조정 전후의 정확도를 비교합니다.

before_accuracy = before_eval["accuracy"]
after_accuracy = after_eval["accuracy"]
improvement = after_accuracy - before_accuracy

print("Before fine-tuning accuracy:", before_accuracy)
print("After fine-tuning accuracy:", after_accuracy)
print("Improvement:", improvement)
Before fine-tuning accuracy: 0.6
After fine-tuning accuracy: 0.8
Improvement: 0.2

이 실험에서 모델의 정확도는 0.60에서 0.80으로 향상했습니다.

이는 20%p 상승으로, 학습 전 50문항 중 30문항에서 정답이었던 것이 미세 조정 후 40문항에서 정답을 낸 결과입니다.

15. 미세 조정된 어댑터 저장 및 업로드

학습된 LoRA 어댑터와 프로세서 파일을 앞서 정의한 출력 디렉터리에 저장합니다.

model.save_pretrained(OUTPUT_DIR)
processor.save_pretrained(OUTPUT_DIR)

print(f"Saved LoRA adapter to: {OUTPUT_DIR}")

다음과 같은 출력이 표시됩니다:

Saved LoRA adapter to: diffusiongemma_pubmedqa_lora

이는 260억 매개변수의 기본 모델 전체 복사본이 아닌, 가벼운 LoRA 어댑터만 저장합니다.

이제 어댑터와 프로세서 파일을 Hugging Face Hub에 업로드합니다:

REPO_ID = "kingabzpro/diffusiongemma_pubmedqa"

model.push_to_hub(REPO_ID)
processor.push_to_hub(REPO_ID)

HF_TOKEN 환경 변수를 RunPod 파드 구성 단계에서 추가했기 때문에 Hugging Face가 자동으로 인증합니다. 토큰이 미리 구성되어 있지 않은 경우에만 notebook_login()을 실행하면 됩니다:

from huggingface_hub import notebook_login

notebook_login()

업로드가 완료되면, 리포지토리에는 이후에 미세 조정된 모델을 로드하는 데 필요한 LoRA 어댑터와 프로세서 구성 파일이 포함됩니다.

Finetuned lora on Hugging face: diffusiongemma_pubmedqa

Source: kingabzpro/diffusiongemma_pubmedqa · Hugging Face 

마무리 생각

Unsloth로 DiffusionGemma를 미세 조정하는 작업은 놀라울 정도로 간단했습니다. 가장 시간이 많이 든 부분은 올바른 의존성을 설치하고, 확산 특화 학습 과정이 어떻게 작동하는지 파악하는 일이었습니다. 환경을 갖춘 뒤에는 모델 로딩, LoRA 어댑터 학습, 평가, 결과를 Hugging Face에 업로드하는 과정이 매우 원활했습니다.

DiffusionGemma가 전통적 언어 모델처럼 한 번에 하나의 토큰을 생성하지 않고, 고정 캔버스를 사용해 디노이징 단계를 통해 잡음 토큰을 점차 정제한다는 점이 특히 흥미로웠습니다. 이와 다른 생성 과정을 이해하고, 생의학 질의응답 과제에 미세 조정해 본 경험은 제게 특히 가치 있었습니다.

작은 설정임에도 50개 샘플에서 정확도가 0.60에서 0.80으로 상승했습니다. 다만 샘플 크기가 작아 오차 범위가 넓고, 이 평가 세트에서는 "항상 yes"라는 단순 기준선만으로도 약 55%가 나옵니다. 

또한 인공 학습 서브셋에는 "maybe" 라벨이 거의 없어, 평가 데이터에 해당 라벨이 등장하더라도 모델이 그 클래스를 학습할 기회가 적습니다. 이는 미세 조정 프로세스의 작동 방식을 살펴보는 빠른 실험으로 받아들이시고, 실제 의료 사용 준비가 되었음을 의미하지는 않습니다.

단일 미세 조정을 넘어설 준비가 되셨나요? 당사의 Developing Large Language Models 트랙은 PyTorch와 transformers의 기초부터 자체 LLM을 구축하고 배포하는 과정까지 안내합니다.

주제

Top LLM Courses

tracks

대형 언어 모델 개발

16
PyTorch와 Hugging Face를 사용하여 최신 딥러닝 및 NLP 기법으로 대규모 언어 모델(LLM)을 개발하는 방법을 배워보세요.
자세히 보기Right Arrow
강좌 시작
더 보기Right Arrow