반응형

아래 링크와 같이 WSL에 설치한 vLLM 서버를 실행하고 사용해 보자.

2026.06.19 - [AI, ML, DL] - [vLLM] WSL 에서 vLLM 설치 및 간단한 실행

 

Background에서 서버를 실행하고 프로세스를 확인.

 

■ 서버 실행하기 (Foreground에서 실행된다)

VLLM_USE_FLASHINFER_SAMPLER=0 python3 -m vllhttp://m.entrypoints.openai.api_server --model LGAI-EXAONE/EXAONE-Deep-2.4B-AWQ --trust_remote_code True --gpu_memory_utilization=0.7

 

■ 서버 실행하기 (Background에서 실행되고 vllm.log 파일에 로그가 기록된다)

VLLM_USE_FLASHINFER_SAMPLER=0 python3 -m vllhttp://m.entrypoints.openai.api_server --model LGAI-EXAONE/EXAONE-Deep-2.4B-AWQ --trust_remote_code True --gpu_memory_utilization=0.7 > vllm.log 2>&1 &

 

VLLM_USE_FLASHINFER_SAMPLER=0은 vLLM이 다음 토큰을 선택(샘플링)할 때 FlashInfer 라이브러리의 고속 커널을 사용하지 않고, PyTorch/Triton 기반의 기본 내장 샘플러를 사용하도록 강제하는 환경 변수 설정이다. 내 시스템에선 이 옵션 없이는 실행할 수 없었다.

 

■ 백그라운드에서 동작중인 서버 프로세스 확인 (백그라운드에서 동작하는 프로세스 중 vllm이라는 문자열과 VLLM이라는 문자열을 검색한다)

ps -ef | grep -E "vllm|VLLM"

 

■ 백그라운드 서버 종료

pkill -f vllhttp://m.entrypoints.openai.api_server

 

 

동작중인 서버를 이용해보자. 아래 코드를 작성하고 실행한다.

from openai import OpenAI

# vLLM 서버 주소 설정 (기본 포트 8000)
client = OpenAI(
    base_url="http://localhost:8000/v1",
    api_key="vllm-token" # api_key는 아무 문자열이나 넣어도 된다.
)

# 단발성 답변 받기 (General Request)
print("=== 일반 답변 요청 ===")
response = client.chat.completions.create(
    model="LGAI-EXAONE/EXAONE-Deep-2.4B-AWQ",  # 동작중인 서버의 모델 이름과 일치해야 한다.
    messages=[
        {"role": "system", "content": "당신은 친절한 AI 도우미입니다."},
        {"role": "user", "content": "인공지능과 거대언어모델(LLM)의 차이점을 한 문장으로 설명해줘."}
    ],
    temperature=0.2,
    top_p=0.95,
    max_tokens=1024
)

print(response.choices[0].message.content)

print()

# 실시간 스트리밍 답변 받기 (Streaming Request)
print("=== 스트리밍 답변 요청 ===")
stream = client.chat.completions.create(
    model="LGAI-EXAONE/EXAONE-Deep-2.4B-AWQ",
    messages=[
        {"role": "system", "content": "당신은 친절한 AI 요리사 도우미 입니다."},
        {"role": "user", "content": "맛있는 김치찌개를 끓이는 비법을 짧게 알려줘."}
    ],
    temperature=0.2,
    top_p=0.95,
    max_tokens=1024,
    stream=True, # 스트리밍 활성화
)

for chunk in stream:
    if chunk.choices[0].delta.content is not None:
        print(chunk.choices[0].delta.content, end="", flush=True)

print()

 

답변 첫 부분에 빈 줄과 </thought> 태그가 따라 나온다.

 

불필요한 태그를 제거해 보자.

from openai import OpenAI

# vLLM 서버 주소 설정 (기본 포트 8000)
client = OpenAI(
    base_url="http://localhost:8000/v1",
    api_key="vllm-token" # api_key는 아무 문자열이나 넣어도 된다.
)

# 단발성 답변 받기 (General Request)
print("=== 일반 답변 요청 ===")
response = client.chat.completions.create(
    model="LGAI-EXAONE/EXAONE-Deep-2.4B-AWQ",  # 동작중인 서버의 모델 이름과 일치해야 한다.
    messages=[
        {"role": "system", "content": "당신은 친절한 AI 도우미입니다."},
        {"role": "user", "content": "인공지능과 거대언어모델(LLM)의 차이점을 한 문장으로 설명해줘."}
    ],
    temperature=0.2,
    top_p=0.95,
    max_tokens=1024
)

#print(response.choices[0].message.content) # 태그 포함 답변 출력
content = response.choices[0].message.content

# </thought> 태그가 포함되어 있다면 분할 처리
if "</thought>" in content:
    # thought_process: 모델이 생각한 과정 (필요시 사용)
    # final_answer: 사용자가 원하는 최종 답변
    thought_process, final_answer = content.split("</thought>", 1)
    #print("=== [AI의 생각 과정] ===")
    #print(thought_process.replace("<thought>", "").strip()) # 시작 태그가 남아있다면 제거
    print(final_answer.strip())
else:
    # 태그가 없는 일반적인 경우 그대로 출력
    print(content)

print()

# 실시간 스트리밍 답변 받기 (Streaming Request)
print("=== 스트리밍 답변 요청 ===")
stream = client.chat.completions.create(
    model="LGAI-EXAONE/EXAONE-Deep-2.4B-AWQ",
    messages=[
        {"role": "system", "content": "당신은 친절한 AI 요리사 도우미 입니다."},
        {"role": "user", "content": "맛있는 김치찌개를 끓이는 비법을 짧게 알려줘."}
    ],
    temperature=0.2,
    top_p=0.95,
    max_tokens=1024,
    stream=True, # 스트리밍 활성화
)

# 실시간 문자열에서 불필요한 </thought> 태그 처리를 위한 변수 선언
full_text = ""
has_passed_thought = False

for chunk in stream:
    if chunk.choices[0].delta.content is not None:
        #print(chunk.choices[0].delta.content, end="", flush=True) # 태그 포함 답변 출력

        token = chunk.choices[0].delta.content
        full_text += token  # 들어오는 토큰을 전체 버퍼에 누적

        # </thought> 태그가 지나갔는지 확인
        if not has_passed_thought:
            if "</thought>" in full_text:
                # 태그가 끝나는 지점을 찾아 그 이후의 텍스트만 추출
                _, final_start_text = full_text.split("</thought>", 1)
                has_passed_thought = True
                
                # 태그 뒤에 공백이나 줄바꿈이 있다면 깔끔하게 지우고 첫 출력
                first_output = final_start_text.lstrip()
                if first_output:
                    print(first_output, end="", flush=True)
            else:
                # 아직 </thought> 태그가 나오기 전(생각 중)이라면 화면에 출력하지 않고 건너뛴다.
                continue
        else:
            # 만약 앞서 출력된 내용이 아직 아무것도 없다면 (sys.stdout이 비어있음)
            # 다음에 들어오는 토큰들도 첫 글자가 나올 때까지 앞쪽 공백/줄바꿈을 계속 지워준다.
            if not full_text.split("</thought>", 1)[1].lstrip():
                # 여전히 공백이나 줄바꿈만 들어오는 상태이므로 출력하지 않고 스킵.
                continue
                
            # 글자가 들어오기 시작하면, 그 시점의 토큰부터 그대로 출력.
            # (단, 공백이 섞여 들어왔을 수 있으므로 첫 진입 토큰만 lstrip 처리)
            if len(full_text.split("</thought>", 1)[1].lstrip()) == len(token):
                print(token.lstrip(), end="", flush=True)
            else:
                print(token, end="", flush=True)

print()

 

불필요한 태그 없이 깔끔하게 정리되었다.

 

 

또한 WSL에 서버를 실행한 상태에서 네이티브 윈도우에서도 위와 동일한 코드로 LLM을 사용할 수 있다.

아니면 WSL에서 hostname -I 명령으로 확인한 IP 주소값을 base_url에 넣어도 된다.

from openai import OpenAI

# vLLM 서버 주소 설정 (기본 포트 8000)
client = OpenAI(
    base_url="http://localhost:8000/v1",
    #base_url="http://172.21.167.101:8000/v1",
    api_key="vllm-token" # api_key는 아무 문자열이나 넣어도 된다.
)

# 단발성 답변 받기 (General Request)
print("=== 일반 답변 요청 ===")
response = client.chat.completions.create(
    model="LGAI-EXAONE/EXAONE-Deep-2.4B-AWQ",  # 동작중인 서버의 모델 이름과 일치해야 한다.
    messages=[
        {"role": "system", "content": "당신은 친절한 AI 도우미입니다."},
        {"role": "user", "content": "인공지능과 거대언어모델(LLM)의 차이점을 한 문장으로 설명해줘."}
    ],
    temperature=0.2,
    top_p=0.95,
    max_tokens=1024
)

print(response.choices[0].message.content)

print()

# 실시간 스트리밍 답변 받기 (Streaming Request)
print("=== 스트리밍 답변 요청 ===")
stream = client.chat.completions.create(
    model="LGAI-EXAONE/EXAONE-Deep-2.4B-AWQ",
    messages=[
        {"role": "system", "content": "당신은 친절한 AI 요리사 도우미 입니다."},
        {"role": "user", "content": "맛있는 김치찌개를 끓이는 비법을 짧게 알려줘."}
    ],
    temperature=0.2,
    top_p=0.95,
    max_tokens=1024,
    stream=True, # 스트리밍 활성화
)

for chunk in stream:
    if chunk.choices[0].delta.content is not None:
        print(chunk.choices[0].delta.content, end="", flush=True)

print()

 

네이티브 윈도우에서 WSL 서버 사용.

 

※ 참고

LG AI Research의 공식 가이드에 따르면 EXAONE Deep 모델은 시스템 프롬프트를 지원하지 않거나 권장하지 않는다. 시스템 프롬프트를 넣으면 모델이 지시사항을 무시하거나 추론(<thought>)을 시작하지 못하고 엉뚱한 답변을 낼 확률이 높아진다. 요리사 같은 페르소나는 아래와 같이 user 메시지 안에 녹여내자.

response = client.chat.completions.create(
    model="LGAI-EXAONE/EXAONE-Deep-2.4B-AWQ",
    messages=[
        # 시스템 프롬프트를 없애고 유저 메시지에 역할을 녹여낸다.
        {"role": "user", "content": "당신은 친절한 AI 도우미입니다. 인공지능과 거대언어모델(LLM)의 차이점을 한 문장으로 설명해줘."}
    ],
    temperature=0.2,
    top_p=0.95,
    max_tokens=1024
)

 

반응형
Posted by J-sean
:
반응형

WSL에서 vLLM을 사용해보자.

 

■ WSL을 설치한다. 운영체제는 우분투 24.04를 설치한다.

우분투 26.04는 파이썬 3.14가 설치되어 있는데 현재 파이토치가 파이썬 3.13까지만 지원하기 때문에 파이토치 설치가 귀찮아진다.

 

■ pip3를 설치한다.

sudo apt update

sudo apt upgrade

sudo apt install python3-pip

pip3 --version (정상 설치 확인)

 

■ 파이썬 가상환경을 만들어 주는 venv를 설치한다.

sudo apt install python3-venv

 

가상환경 생성 및 확인

 

가상환경 활성화

■ venv-vllm 디렉토리에 가상환경을 생성하고 활성화한다.

python3 -m venv venv-vllm

source venv-vllm/bin/activate

 

 

■ 파이토치를 설치한다. (CUDA 12.4)
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124

 

vllm을 설치하면 많은 프로그램이 설치된다.

■ vLLM을 설치한다.

pip3 install vllm

 

■ vLLM을 실행하기 위해 CUDA Toolkit을 설치한다. (Cuda Toolkit 12.4)

wget https://developer.download.nvidia.com/compute/cuda/12.4.0/local_installers/cuda_12.4.0_550.54.14_linux.run

sudo sh cuda_12.4.0_550.54.14_linux.run

위 명령을 실행하면 잠시 멈춘 것처럼 시간이 좀 걸린다. 그리고 accept를 입력하고 다음 화면에서 CUDA Toolkit 12.4가 선택된 상태에서 Install을 선택한다. Driver는 옵션에 없었지만 있다면 선택해제한다. Driver를 설치하는 것이 아니다.

 

설치가 끝나면 아래와 같이 환경 변수를 등록한다.

nano ~/.bashrc 실행하고 파일 끝에 아래 내용 추가

export PATH=/usr/local/cuda-12.4/bin${PATH:+:${PATH}}
export LD_LIBRARY_PATH=/usr/local/cuda-12.4/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}

source ~/.bashrc 실행 (이 명령을 실행하고 나면 파이썬 가상환경이 풀린다)
nvcc --version 명령을 실행하면 버전이 표시된다.

 

 

■ vLLM에서 LGAI EXAON 모델을 사용하는 예

import os

# vLLM에서 FlashInfer 기반의 고속 셈플링(Sampling) 기능을 끄고, 안정적인 PyTorch 네이티브(기본)
# 셈플링 방식으로 되돌리기(Fallback).
os.environ["VLLM_USE_FLASHINFER_SAMPLER"] = "0"
# vLLM은 내부적으로 가속 연산을 위해 FlashInfer라는 라이브러리를 사용하는데 이 라이브러리는
# NVIDIA Turing 아키텍처(Compute Capability sm75) 이상의 GPU에서만 작동한다. 사용하는 그래픽카드가
# 소형 모델 구동용(VRAM 8GB 수준)이면서 sm75보다 낮은 구형 아키텍처(예: GTX 10시리즈인 Pascal 아키텍처 sm61 등)
# 이면 문제가 발생한다.
# 해결 방법: vllm 패키지를 로드하기 전에 os.environ을 통해 FlashInfer 가속 비활성화하기

from vllm import LLM, SamplingParams

def main():
    # 모델 로드
    llm = LLM(
        model="LGAI-EXAONE/EXAONE-Deep-2.4B-AWQ", 
        trust_remote_code=True, 
        gpu_memory_utilization=0.7
    )
# vLLM은 기본적으로 GPU 메모리의 90%(0.9)를 미리 할당하기 때문에, 낮은 성능의 GPU에서는
# OOM(메모리 부족) 에러를 방지하거나 다른 프로세스와 GPU를 나누어 쓰려면 gpu_memory_utilization
# 옵션이 필수적이다.

    # 파라미터 설정
    sampling_params = SamplingParams(
        temperature=0.0,
        top_p=0.95,
        max_tokens=1024,
        repetition_penalty=1.1
    )

    # 질문 리스트
    raw_questions = [
        "대한민국의 수도는 어디인가요?",
        "인공지능은 무엇인가요?"
    ]

    # vLLM 공식 Chat Template 적용
    prompts = []
    tokenizer = llm.get_tokenizer()
    for q in raw_questions:
        messages = [{"role": "user", "content": q}]
        formatted_prompt = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
        prompts.append(formatted_prompt)

    # 텍스트 생성
    outputs = llm.generate(prompts, sampling_params)

    # 결과 출력 (내장함수로 태그 뒤쪽만 추출)
    for i, output in enumerate(outputs):
        prompt = raw_questions[i]
        # output.prompt로 프롬프트를 추출할 수도 있지만 불필요한 태그가 많이 따라온다. 정제과정이 필요.
        generated_text = output.outputs[0].text
        
        # </thought> 태그가 존재한다면 그 태그 뒷부분([1])만 추출한다
        if "</thought>" in generated_text:
            clean_answer = generated_text.split("</thought>")[1]
        else:
            clean_answer = generated_text

        print(f"==========================================")
        print(f"질문: {prompt}")
        print(f"답변: {clean_answer.strip()}")
        print(f"==========================================\n")

if __name__ == "__main__":
    main()

 

EXAON 모델이 다운로드되어 있지 않다면 다운로드하느라 이 화면에서 시간이 좀 걸린다.

위 코드에서는 토큰 없이 허가되지 않은 접근을 하고 있기 때문에 다운로드가 느리다고 한다. 토큰을 받고 빠르게 다운로드하는 방법은 맨 아래 내용을 참고하자.

 

최종 결과 화면

 

 

다시 실행하면 모델을 다운로드하는 과정이 없다.

 

import os
os.environ["VLLM_USE_FLASHINFER_SAMPLER"] = "0"

from vllm import LLM, SamplingParams

def main():
    llm = LLM(
        model="LGAI-EXAONE/EXAONE-Deep-2.4B-AWQ", 
        trust_remote_code=True, 
        gpu_memory_utilization=0.7
    )

    sampling_params = SamplingParams(
        temperature=0.0,
        top_p=0.95,
        max_tokens=1024,
        repetition_penalty=1.1
    )

    raw_questions = [
        "대한민국의 수도는 어디인가요?",
        "인공지능에 대해 한 문장으로 요약해줘."
    ]

    prompts = []
    tokenizer = llm.get_tokenizer()
    for q in raw_questions:
        messages = [{"role": "user", "content": q}]
        formatted_prompt = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
        prompts.append(formatted_prompt)

    outputs = llm.generate(prompts, sampling_params)

    for i, output in enumerate(outputs):
        prompt = raw_questions[i]
        generated_text = output.outputs[0].text
        
        if "</thought>" in generated_text:
            clean_answer = generated_text.split("</thought>")[1]
        else:
            clean_answer = generated_text

        print(f"==========================================")
        print(f"질문: {prompt}")
        print(f"답변: {clean_answer.strip()}")
        print(f"==========================================\n")

    print(outputs)

if __name__ == "__main__":
    main()

 

짧은 답변이 나오도록 질문을 바꾸고 전체 결과가 출력되도록 print(outputs) 명령을 추가했다.

 

마지막에 outputs의 내용이 출력되었다.

 

[RequestOutput(request_id=0, prompt='[|system|][|endofturn|]\n[|user|]대한민국의 수도는 어디인가요?\n[|assistant|]<thought>\n', prompt_token_ids=[420, 453, 47982, 453, 422, 361, 560, 420, 453, 14719, 453, 422, 36437, 730, 8952, 657, 4083, 798, 7799, 392, 560, 420, 453, 1167, 8659, 453, 422, 389, 52040, 391, 560], encoder_prompt=None, encoder_prompt_token_ids=None, prompt_logprobs=None, outputs=[CompletionOutput(index=0, text='\n</thought>\n\n 대한민국의 수도는 서울(Seoul)입니다.', token_ids=[560, 2240, 52040, 391, 560, 560, 9971, 730, 8952, 657, 2879, 369, 8078, 10103, 370, 10996, 375, 361], routed_experts=None, cumulative_logprob=None, logprobs=None, finish_reason=stop, stop_reason=None)], finished=True, metrics=None, lora_request=None, num_cached_tokens=0), RequestOutput(request_id=1, prompt='[|system|][|endofturn|]\n[|user|]인공지능에 대해 한 문장으로 요약해줘.\n[|assistant|]<thought>\n', prompt_token_ids=[420, 453, 47982, 453, 422, 361, 560, 420, 453, 14719, 453, 422, 41595, 22427, 2373, 2409, 764, 13742, 13456, 16399, 999, 15887, 375, 560, 420, 453, 1167, 8659, 453, 422, 389, 52040, 391, 560], encoder_prompt=None, encoder_prompt_token_ids=None, prompt_logprobs=None, outputs=[CompletionOutput(index=0, text='\n</thought>\n\n인간의 intelligence를 computer로 구현하는 것.', token_ids=[560, 2240, 52040, 391, 560, 560, 25284, 730, 13887, 4605, 6458, 715, 19495, 1130, 657, 924, 375, 361], routed_experts=None, cumulative_logprob=None, logprobs=None, finish_reason=stop, stop_reason=None)], finished=True, metrics=None, lora_request=None, num_cached_tokens=0)]

 

 

그런데 이렇게 진행하는 모델은 내부에 config.json 파일이 있어야 한다. (정확히는 gguf 포맷의 모델은 바로 사용할 수 없다는 것이다)

예를 들어 EXAON은 config.json 파일이 있지만 Bllossom-3B-gguf-Q4_k_M은 없다. 그래서 Bllossom-3B-gguf-Q4_k_M은 vLLM에서 바로 사용할 수 없다. (아래 참고 1~2를 참고한다)

 

config.json 파일이 없다. (gguf 포맷 모델이므로)

 

config.json 파일이 없다는 에러가 발생한다.

 

config.json 파일이 있다.

 

config.json 파일이 있다.

 

 

※ 참고 1

■ Hugging Face에서 (Bllossom-3B-gguf-Q4_K_M) 모델 다운로드하기

hf 명령어를 사용한다. huggingface-cli는 더 이상 사용하지 않는다. 위 과정을 진행했다면 hf(Hugging Face Hub CLI)는 이미 설치되어 있다.

파이썬 가상화 환경을 시작한다.

hf auth login
Paste an access token 옵션을 선택하고 Profile - Settings - Access Tokens에서 생성한 토큰을 붙여넣는다.
로그인이 완료된다.

로그인 확인하기
hf auth whoami

Bllossom-3B-gguf-Q4_K_M 모델 다운로드하기
hf download Bllossom/llama-3.2-Korean-Bllossom-3B-gguf-Q4_K_M
로그인하지 않은 상태에서 다운로드하면 느리게 진행되지만 로그인을 했으므로 빠르게 진행된다.

모델 다운로드 위치
/home/sean/.cache/huggingface/hub/
예) /home/sean/.cache/huggingface/hub/models--Bllossom--llama-3.2-Korean-Bllossom-3B-gguf-Q4

 

※ 참고 2

Bllossom-3B-gguf-Q4_K_M 같은 gguf 포맷 모델 저장소에는 config.json 파일이 포함되어 있지 않다. guff 파일은 모델의 가중치뿐만 아니라 토크나이저 설정, 레이어 수, 아키텍처 정보 등 config.json에 들어가는 모든 메타데이터를 단일 guff 파일 내부에 바이너리 형태로 통합하여 저장하기 때문이다. 모델의 메타데이터와 아키텍처 구조를 확인하거나 다른 라이브러리와 호환을 맞추기 위해 json 파일이 필요하다면 양자화되기 전 원본 모델 저장소인 Bllossom/llama-3.2-Korean-Bllossom-3B에 있는 config.json 및 토크나이저 설정 파일들을 사용하면 된다. (설정 파일을 직접 다운로드 받아 gguf 파일이 있는곳에 저장할 필요는 없다)

 

llm = LLM(
        model="/home/sean/.cache/huggingface/hub/models--Bllossom--llama-3.2-Korean-Bllossom-3B-gguf-Q4_K_M/snapshots/c07b7a0f2688d1212612b653a752a0dfe4e18bae/llama-3.2-Korean-Bllossom-3B-gguf-Q4_K_M.gguf",
        # 모델은 저장된 경로와 이름을 정확히 적어준다.
        tokenizer="Bllossom/llama-3.2-Korean-Bllossom-3B",
        # 토크나이저는 저장소 이름을 적어줘도 된다.
        trust_remote_code=True,
        gpu_memory_utilization=0.7,
        dtype="float16",
    )

하지만 위와 같이 LLM 클래스를 생성하면 될 것 같은데, WSL에서 실행하면 계속 UVA 관련 에러가 발생한다. WSL이 아닌 리눅스를 네이티브 운영체제로 사용하는 환경에서 테스트해 봐야 할 것 같다.

 

또한 vLLM에서 gguf 포맷 모델 사용은 실험적 단계이며 특별한 제약과 조건이 있어 추천하지 않는다. vLLM은 AWQ, GPTQ, FP8 같은 GPU 네이티브 양자화 포맷에서 제대로 된 성능이 나온다. gguf 포맷 모델을 로컬 환경에서 편하고 안정적으로 사용하려면 Ollama를 사용하자.

 

GGUF(GPT-Generated Unified Format)는 인공지능 모델(특히 LLM)을 개인 PC나 노트북 같은 로컬 환경에서 빠르고 효율적으로 실행하기 위해 설계된 단일 파일 모델 포맷이다.

3B: 모델의 매개변수가 30억 개이다. (3 Billion)

Q4: 4비트 양자화를 의미. 원래 16비트인 모델을 4비트로 압축하여 파일 용량과 메모리를 1/4로 줄였다는 뜻.

K_M: 양자화 기법의 종류. 보통 _L(Large), _M(Medium), _S(Small) 로 나뉘며, Q4_K_M은 성능 저하를 최소화하면서 용량을 줄인 가장 대중적이고 밸런스가 좋은 기법이다.

 

■ UVA

WSL에서 UVA는 일반적으로 엔비디아(NVIDIA)의 Unified Virtual Addressing(통합 가상 주소) 기술을 의미합니다.
이는 GPU가 컴퓨터 메모리(RAM)와 GPU 자체 메모리를 하나의 주소 공간으로 다룰 수 있게 해주는 기술입니다. WSL 환경에서는 AI/머신러닝(예: PyTorch)을 구동할 때 GPU 가속을 위해 필수적으로 사용되는 핵심 기능입니다.

WSL에서 UVA가 중요한 이유
1. 메모리 접근 단순화: CPU 메모리와 GPU 메모리 간의 데이터를 복사할 때 위치를 일일이 지정할 필요가 없습니다.
2. AI 및 딥러닝 가속: vLLM이나 대형 모델(LLM) 학습 시 VRAM 부족을 해결하기 위해 CPU RAM을 공유해 사용할 때(CPU Offloading), 이 기술이 필수적으로 작동해야 합니다.
3. 호환성 이슈 해결: 종종 WSL 환경에서 이 기능이 제대로 감지되지 않으면 메모리 오류가 발생하거나 가속 기능이 작동하지 않을 수 있습니다.

 

 

 

※ 참고 3

파일 익스플로러 주소창에 \\wsl$를 입력하면 WSL에 설치된 운영체제의 파일에 접근할 수 있다. 물론 왼쪽 패널에 Linux - Ubuntu-24.04로 접근해도 된다.

 

※ 참고 4

vLLM Documentation

vLLM GitHub

 

반응형
Posted by J-sean
:
반응형

Ollama를 설치하고 사용해 보자.

Documentation

API Reference

 

Windows 버전을 설치한다.

 

 

특별한 옵션도 없고 그냥 설치하면 된다.

 

help

 

아직 설치된 모델이 없다.

 

 

llava 모델을 설치하고 사용해 보자. LLava 모델은 한글 사용이 가능하지만 자연스럽지는 않다.

Large Language and Vision Assistant

 

ollama pull llava

 

 

ollama run llava를 실행하면 llava 모델이 실행된다.

 

D:\D\My project\C\bus.jpg

 

 

질문을 입력하면 답변이 출력된다.

 

답변은 영어로 나오지만 한글 질문도 알아듣는다.

 

이미지 경로를 다시 입력하지 않아도 정확히 인식한다.

 

llava 모델의 경우 자연스럽지는 않지만 한글 출력도 가능하다.

 

모델 삭제

 

※ 참고

vLLM

vLLM Documentation

vLLM GitHub

 

반응형
Posted by J-sean
: