Codex 와 Local LLM 연결하기

Local LLM 시리즈

  1. (Local LLM) Ollama 시작하기
  2. Codex 와 Local LLM 연결하기

Codex 와 Local LLM 연결하기

Codex 를 Local LLM 로 서빙하는 API End point 에 연동해 사용하는 방법을 정리 요약한다.

  1. codexcli: 0.134 (20260526 설치)
  2. client: Ausus A14 / RTX 4060 8GB
  3. server: RTX 3080ti

설치와 시작

codex 를 설치하고 프로젝트 폴더에서 codex를 실행한다.

프로젝트를 시작하면 .codex/ 폴더의 config.toml 설정 파일에 [projects.] 섹션이 생성된다.

프로젝트 섹션에 codex 를 시작한 폴더가 설정된다.

1
2
3
4
5
6
7
8
# .codex/config.toml
personality = "pragmatic"

[projects."/home/user/My_Project"]
trust_level = "trusted"

[tui.model_availability_nux]
"gpt-5.5" = 4

모델 Provider 설정

config.toml[model_providers.] 섹션에 LLM endpoint 를 명시적으로 설정할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# .codex/config.toml
personality = "pragmatic"

[projects."/home/user/My_Project"]
trust_level = "trusted"

[model_providers.goyangi]
name = "openai" # openai chat
base_url = "http://192.168.0.3:8001" # llama-server
wire_api = "responses"
requires_openai_auth = false

[model_providers.local_llm]
name = "openai"
base_url = "http://localhost:11434/v1" # openai endpoint /v1 지정 필요
wire_api = "responses"
requires_openai_auth = false


[tui.model_availability_nux]
"gpt-5.5" = 4
  • wire_api = "responses" : 최신 버전의 codex 는 response 로 지정해야 한다고 한다.

모델에 대한 provider 설정을 알아보자.


프로파일 설정

config.toml 의 model_providers 의 선언한 provider 이름은 별도의 동일한 파일로 설정한다.

해당 provider 의 동일 이름의 .codex/PROFILENAME.tomy 파일을 참조하게 된다.

이곳에 LLM endpoiint 의 세부 모델에 대한 파라미터를 선언한다.

예를 들의 위의 goyangi_coder 는 다음 같이 구성된다.

1
2
3
4
5
6
7
#.codex/goyangi_coder.config.toml
model_provider = "goyangi"
model = "gpt-5"
approvals_reviewer = "user"
# 필요 시 추가 옵션
# max_tokens = 2048
# context_length = 8192

다른 프로바이더 local_llm 프로파일은 다음 같이 구성된다.

1
2
3
4
5
6
7
#.codex/local_llm.config.toml
model_provider = "local_llm"
model = "gemma-4" # 서비스가 제공하는 정확안 모델 이름
approvals_reviewer = "user"
# 필요 시 추가 옵션
# max_tokens = 2048
# context_length = 8192

시작

프로파일을 사용해서 codex 를 시작할 수 있다.

1
codex --profile local_llm

테스트

1
curl http://192.168.0.3:8001/v1/models

반환된 JSON 결과의 id 값이 "gemma-4"가 아니라 파일명 전체(예: "gemma-4-it-Q4_K_M.gguf")로 되어 있다면, 그 값을 그대로 model 필드에 적어주어야 매칭 실패 에러가 나지 않습니다.


한국어

Linux에서 Codex 한글 설정
Linux는 시스템 로케일이 UTF-8이면 추가 설정 없이 정상 작동합니다. locale 명령으로 확인하세요.

locale

LANG=ko_KR.UTF-8 또는 en_US.UTF-8이면 정상

만약 UTF-8이 아니라면:

sudo locale-gen ko_KR.UTF-8

sudo update-locale LANG=ko_KR.UTF-8

(Local LLM) Ollama 시작하기

Local LLM 시리즈

  1. (Local LLM) Ollama 시작하기
  2. Codex 와 Local LLM 연결하기

Ollama 란

ollama 는 LLM model 을 local machine 에서 서버로 서비스를 제공할 수 있는 플랫폼이다.

  • ollama 제공 및 외부 LLM Model 을 서버 및 채팅 제공 CLI
  • LLM model 파라미터 조정

Gemini 통해 그린 ollama 서비스 다이어그램.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
┌────────────────────────────────────────────────────────────────────────┐
│ Windows 11 Host (ASUS A14 / RTX 4060 Laptop GPU 8GB) │
│ │
│ ┌────────────────────────┐ [Mirrored Network Mode] │
│ │ Windows App / IDE │ - Ports are shared directly │
│ │ (VS Code, Cursor 등) │ - No Port Forwarding Needed │
│ └───────────┬────────────┘ │
│ │ (HTTP Request to localhost:11434) │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ WSL2 Ubuntu Environment (goyangi2) │ │
│ │ │ │
│ │ ollama.service [systemd] │ │
│ │ └── Port: 0.0.0.0:11434 (LISTENING) │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ Ollama Runner (llama.cpp / GGML Backend) │ │ │
│ │ └──────────────────────┬───────────────────────┘ │ │
│ └────────────────────────────────┼───────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼───────────────────────────────┐ │
│ │ NVIDIA CUDA Driver Layer │ │
│ └────────────────────────────────┬───────────────────────────────┘ │
│ │ (100% GPU Offload) │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ RTX 4060 VRAM (8GB) Dedicated Memory │ │
│ │ ├── Model Weights (Gemma 4 4.6B Q5) ─── [ 5.4 GiB ] │ │
│ │ ├── KV Cache (num_ctx: 12288) ───────── [ 392.0 MiB ] │ │
│ │ └── Compute Graph (CUDA0) ───────────── [ 302.0 MiB ] │ │
│ │ │ │
│ │ └── [ 🚀 Total GPU Memory Used: 6.6 GiB / 8.0 GiB ] │ │
│ └────────────────────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────────────────┘

ollama 설치

ollama CLI 와 Model 은 아래 사이트에서 다운로드 받을 수 있다.

설치후 LLM Chat, API call, Codex / Claude CLI 에 연동해서 사용할 수 있다.


설치

https://ollama.com/download/linux

1
curl -fsSL https://ollama.com/install.sh | sh

ollama CLI 명령

ollama CLI 명령

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ ollama
Ollama 0.21.2

▸ Chat with a model
Start an interactive chat with a model

Launch OpenClaw (install)
Personal AI with 100+ skills

Launch Claude Code
Anthropic's coding tool with subagents

Launch OpenCode (not installed)
Anomaly's open-source coding agent

More...
Show additional integrations

사용 가능한 명령:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Usage:
ollama [flags]
ollama [command]

Available Commands:
serve Start Ollama
create Create a model
show Show information for a model
run Run a model
stop Stop a running model
pull Pull a model from a registry
push Push a model to a registry
signin Sign in to ollama.com
signout Sign out from ollama.com
list List models
ps List running models
cp Copy a model
rm Remove a model
launch Launch the Ollama menu or an integration
help Help about any command

Flags:
-h, --help help for ollama
--nowordwrap Don't wrap words to the next line automatically
--verbose Show timings for response
-v, --version Show version information

Use "ollama [command] --help" for more information about a command.

모델 다운로드 pull 명령으로 ollama 저장소 제공 모델 다운로드할 수 있다.


[pull 명령]

pull 명령으로 모델을 다운로드 한다.

1
2
3
$ ollama pull gemma4:e2b
pulling manifest
pulling 4e30e2665218: 2% ▕█ ▏ 109 MB/7.2 GB 56 MB/s 2m5s

pull 로 다운받은 모델 저장 디렉토리:

  • /usr/share/ollama/.ollama/models :(시스템 서비스 실행 시)

[Ollama 경로 변경]

Ollama는 환경 변수 OLLAMA_MODELS 를 참조합니다.

1
export OLLAMA_MODELS="/data/models/ollama"

설정 후 source ~/.bashrc와 sudo systemctl restart ollama를 잊지 마세요.


[ls 명령]

모델 목록 조회

1
2
3
4
5
6
$ ollama ls
NAME ID SIZE MODIFIED
gemma4:e2b 7fbdbf8f5e45 7.2 GB 3 days ago
gemma4-e4b-32k:latest 6d2a1a196ef9 9.6 GB 4 weeks ago
gemma4:e4b c6eb396dbd59 9.6 GB 4 weeks ago
qwen2.5-coder:latest dae161e27b0e 4.7 GB 4 weeks ag
  • gemma4-e4b: 다운로드한 원래 모델
  • gemma4-e4b-32k: 모델의 파라미터를 수정한 Modelfile 에서 생성한 새 모델

[rm 명령]

rm 명령으로 다운 받은 모델을 삭제한다.

1
ollama rm gemma4:e4b

[show 명령]

show 명령으로 모델의 세부 정보를 조회할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$ ollama show gemma4:e4b
Model
architecture gemma4
parameters 8.0B
context length 131072
embedding length 2560
quantization Q4_K_M
requires 0.20.0

Capabilities
completion
vision
audio
tools
thinking

Parameters
temperature 1
top_k 64
top_p 0.95

License
Apache License
Version 2.0, January 2004
...

[run 명령]

run 명령은 ollama 모델로 다운받은 NAME 이름의 모델을 서비스로 시작해 준다.

  • 시스템의 ollama 서비스를 시작해 http로 11434 포트를 통해서 제공된다.
  • run 명령은 CLI 채팅을 시작
1
2
3
4
ollama run gemma4:e2b
>>> Send a message (/? for help)
>>>
Use Ctrl + d or /bye to exit

run NAME 명령 혹은 serve 명령으로 시스템 서비스로 11434 포트를 통해 웹서비스가 시작된다.

1
2
3
$ sudo ss -tunlp | grep ollama
tcp LISTEN 0 4096 127.0.0.1:35965 0.0.0.0:* users:(("ollama",pid=824718,fd=3))
tcp LISTEN 0 4096 127.0.0.1:11434 0.0.0.0:* users:(("ollama",pid=165,fd=3))

브라우저로 11434 포트에 접속해 보면 ‘Ollama is running’ 을 확인 가능하다.


[ps 명령]

ps 명령은 실행중인 ollama 프로세스를 확인할 수 있다.

1
2
3
$ ollama ps
NAME ID SIZE PROCESSOR CONTEXT UNTIL
gemma4:e2b 7fbdbf8f5e45 7.7 GB 75%/25% CPU/GPU 4096 4 minutes from now

systemd 상태를 확인한다.

1
2
3
4
5
6
7
$ systemctl status ollama
● ollama.service - Ollama Service
Loaded: loaded (/etc/systemd/system/ollama.service; enabled; preset: enabled)
Active: active (running) since Fri 2026-05-29 22:02:07 KST; 9h ago
Main PID: 165 (ollama)
Tasks: 25 (limit: 28826)

로그 확인

1
2
3
4
5
$ journalctl -u ollama -f
5월 29 07:42:11 goyangi2 ollama[165]: time=2026-05-29T07:42:11.649+09:00 level=INFO source=server.go:1398 msg="waiting for server to become available" status="llm server loading model"
5월 29 07:42:19 goyangi2 ollama[165]: time=2026-05-29T07:42:19.188+09:00 level=INFO source=server.go:1402 msg="llama runner started in 69.72 seconds"
5월 29 07:42:19 goyangi2 ollama[165]: [GIN] 2026/05/29 - 07:42:19 | 200 | 1m10s | 127.0.0.1 | POST "/api/generate"


[OpenAI API 호환 엔드포인트]

Ollama는 별도의 설정 없이도 OpenAI와 호환되는 API 엔드포인트를 기본적으로 제공합니다.


[stop 명령]

1
ollama stop

ollama 시스템 서비스를 시작한다.

1
ollama serve

systemd 를 직접 종료할 수 있겠다.

1
sudo systemctl stop ollama

서비스 환경변수 확인

1
$ sudo systemctl show ollama --property=Environment


ollama 서비스 End-point

Core Native EndpointsWhen interacting directly with the native Ollama API, use these specific resource paths:

Text Generation: POST http://localhost:11434/api/generate
Chat Completions: POST http://localhost:11434/api/chat
Embeddings: POST http://localhost:11434/api/embed
List Local Models: GET http://localhost:11434/api/tags

Compatibility Endpoints
If you are integrating Ollama into third-party tools that expect specific provider structures, use these base URLs:OpenAI Compatible Base URL: Use http://localhost:11434/v1 (e.g., chat completions map to /v1/chat/completions).Anthropic Compatible Base URL: Use http://localhost:11434 with standard paths like /v1/messages.What programming language, framework, or appli



Modelfile 로 성능 조정

ollama 는 Modelfile 을 이용해 기존 모델의 파라미터를 조정해 새로운 모델로 서빙할 수 있다.

모델파일

Modelfile 은 텍스트 파일로 특정 모델의 파라미터, 프롬프를 조정해 새로운 모델로 생성할 수 있다.


모델은 ls 명령의 1) 목록에 나타난 모델을 사용하거나, 2) gguf 경로를 FROM 구문에 사용하면 된다.

1
2
3
4
5
6
7
$ ollama ls
NAME ID SIZE MODIFIED
qwen3-14b-han:latest bb1dc5fee044 9.0 GB 10 hours ago
hf.co/unsloth/Qwen3-14B-GGUF:Q4_K_M 1c75fc1b9127 9.0 GB 10 hours ago
gemma4-e4b-32k:latest 2bb4cc1b3660 9.6 GB 3 days ago
my-default:latest 2bb4cc1b3660 9.6 GB 3 days ago
gemma4:e4b c6eb396dbd59 9.6 GB 3 days ago
  1. num_ctx 토큰량 수정

ollama 모델에 할당한 **Context Window(문맥 창)**가 4096 으로 제한, Ollama에서 모델을 실행할 때 기본적으로 설정되는 컨텍스트 크기를 직접 지정

  1. 터미널에서 Modelfile을 생성합니다.

Modelfile 작성:

1
2
3
FROM qwen2.5-coder:7b
# 컨텍스트 크기를 32768(32k)로 설정
PARAMETER num_ctx 32768
  1. 새 파라미터로 모델을 생성
1
ollama create qwen-7b-32k -f Modelfile

새 모델 런치

1
ollama run qwen-7b-32k
  1. GPU 가속 최적화 (GPU Layers 설정)

Ollama는 기본적으로 GPU에 모델 레이어를 분배하지만, 때때로 VRAM 여유가 있음에도 일부를 CPU(RAM)에 남겨두는 경우가 있습니다. 모든 연산을 GPU에서 처리하도록 강제하면 속도가 비약적으로 향상됩니다.

  • Modelfile 수정:
1
2
3
4
5
FROM qwen2.5-coder:7b
PARAMETER num_ctx 32768
# 7b 모델은 보통 28~32개의 레이어로 구성됩니다.
# -1은 가능한 모든 레이어를 GPU에 올리라는 뜻입니다.
PARAMETER num_gpu -1
  • 적용: ollama create qwen-7b-32k -f Modelfile 후 실행.

2. KV 캐시 양자화 (Flash Attention 및 메모리 절약)

32k와 같은 긴 컨텍스트를 사용할 때 가장 많은 메모리를 잡아먹는 것은 모델 자체보다 KV Cache(이전 대화를 기억하는 메모리)입니다. Ollama 최신 버전에서는 이를 압축하여 VRAM 부담을 줄일 수 있습니다.

  • 설정 방법: (시스템 환경 변수에 추가)
    WSL2 터미널에서 nano ~/.bashrc를 열고 아래 줄을 추가하세요.
    1
    2
    export OLLAMA_FLASH_ATTENTION=1
    export OLLAMA_KV_CACHE_TYPE=q8_0 # 또는 f16(기본), q4_0(더 많은 절약)
  • 효과: OLLAMA_FLASH_ATTENTION은 RTX 4060 같은 Ampere 아키텍처에서 추론 속도를 대폭 높여주고, KV_CACHE_TYPE을 양자화하면 긴 문맥에서도 VRAM 부족으로 인한 속도 저하(Fallback)를 방지합니다.

3. 하드웨어 스케줄링 및 전원 관리 (Windows/WSL2 공통)

RTX 4060 Laptop GPU를 사용 중이시라면 하드웨어 설정이 큰 차이를 만듭니다.

  • 하드웨어 가속 GPU 일정 예약 (HAGS): Windows 설정에서 이 기능을 으로 설정하세요. WSL2의 GPU 할당 효율이 좋아집니다.
  • NVIDIA 제어판: 전원 관리 모드를 **”최고 성능 선호”**로 변경하세요. 노트북 환경에서는 클럭 제한이 걸려 추론 속도가 출렁일 수 있습니다.

4. Claude Code와의 협업 최적화 (Ignore 파일 활용)

Claude Code는 프로젝트의 전체 맥락을 읽으려 시도합니다. 불필요한 데이터가 32k 컨텍스트를 채우지 않도록 관리해야 모델의 “두뇌”가 코딩에만 집중할 수 있습니다.

  • .claudeignore 파일 생성: 프로젝트 루트에 파일을 만들고 아래 내용을 추가하세요.
    1
    2
    3
    4
    5
    6
    node_modules/
    dist/
    *.log
    .git/
    venv/
    # 분석에 불필요한 대형 바이너리나 데이터 파일들 제외
  • 효과: 모델이 읽어야 할 정보의 밀도가 높아져서 답변의 정확도(Quality)가 올라갑니다.

실시간 모니터링 팁

설정을 바꾼 후 실제로 GPU가 열일하고 있는지 확인하는 습관이 중요합니다.

  • Windows: 작업 관리자 > 성능 > GPU 0 (또는 1)에서 Dedicated GPU Memory 사용량을 확인하세요. 8GB에 육박하되 넘치지 않는 상태가 베스트입니다.
  • WSL2: 터미널에서 nvidia-smi를 입력해 현재 Ollama가 점유 중인 VRAM 용량을 체크하세요.

로그 조회

~$ journalctl -u ollama -n 100 –no-pager



외부모델 사용

ollama 는 모델을 정의한 파일을 통해 사용자 튜닝을 할 수 있다.

hf.co 이용

Ollama에서 허깅페이스에서 가장 빠르게 내려받아 실행하는 방법은 hf.co 주소를 직접 사용하는 것입니다.

1
ollama run hf.co/[유저명]/[저장소명]:[양자화태그]

DeepSeek-V4-Flash 모델 다운로드

1
ollama pull hf.co/unsloth/DeepSeek-V4-Flash-GGUF

DeepSeek-V4-Flash 모델을 Q4_K_M 양자화 버전

1
ollama pull hf.co/unsloth/DeepSeek-V4-Flash-GGUF:Q4_K_M

[저장 위치]

먼저 현재 모델들이 어디에 쌓이고 있는지 확인해야 합니다.

  • Ollama: /usr/share/ollama/.ollama/models (시스템 서비스 실행 시) 또는 ~/.ollama/models
  • Hugging Face: ~/.cache/huggingface/hub

Hugging Face 경로 변경

환경 변수를 통해 간단히 변경할 수 있습니다. ~/.bashrc 파일을 열고 아래 내용을 추가하세요.

1
export HF_HOME="/data/models/huggingface"

curl

허깅페이스 모델 파일의 다운로드 링크 Url 을 이용.

1
curl -L https://huggingface.co/unsloth/DeepSeek-V4-Flash-GGUF/resolve/main/DeepSeek-V4-Flash-Q4_K_M.gguf -o deepseek-v4.gguf

Modelfile 생성

다른 저장소의 모델을 ollama 에서 서빙하려면 Modelfile 작성해서 사용해야 한다.

다음은 unsloth/Qwen3-14B-GGUF:Q4_K_M 모델을 위한 모델 파일이다.

1
2
3
# Modelfile
FROM hf.co/unsloth/Qwen3-14B-GGUF:Q4_K_M
#FROM ./DeepSeek-V4-Flash-Q4_K_M.gguf # 파일명 경로

ollama 모델 빌드

1
2
ollama create ds-v4 -f Modelfile
ollama run ds-v4

외부 모델 파일 사용

별도로 다운로드한 gguf 모델을 사용할 수 있다.

1
2
3
4
5
FROM /home/Models/unsloth/gemma-4-E2B-it-Q5_K_M.gguf
# 컨텍스트 크기를 16384(16k), 32768(32K)로 설정
PARAMETER num_ctx 16384
# -1은 가능한 모든 레이어를 GPU에 올리라는 뜻입니다```
PARAMETER num_gpu 15

gemma4-e2b-16k 이름으로 모델을 생성한다.

1
ollama create gemma4-e2b-16k -f Modelfile

확인

1
2
3
$ ollama ls
NAME ID SIZE MODIFIED
gemma4-e2b-16k:latest d1ac4306a92e 3.4 GB 5 minutes ago

모델 run

1
2
3
4
5
6
$ ollama run gemma4-e2b-16k
>>>/bye

$ ollama ps
NAME ID SIZE PROCESSOR CONTEXT UNTIL
gemma4:e2b 7fbdbf8f5e45 7.7 GB 75%/25% CPU/GPU 4096 4 minutes from no

주요파라미터

1
2
3
4
5
6
7
8
9
10
11
12
13

#### 프롬프트 템플릿 적용

모델은 `ollama ls` 명령의 목록에 나타난 모델을 사용하거나 gguf 경로를 `FROM` 구문에 사용하면 된다.

```bash
$ ollama ls
NAME ID SIZE MODIFIED
qwen3-14b-han:latest bb1dc5fee044 9.0 GB 10 hours ago
hf.co/unsloth/Qwen3-14B-GGUF:Q4_K_M 1c75fc1b9127 9.0 GB 10 hours ago
gemma4-e4b-32k:latest 2bb4cc1b3660 9.6 GB 3 days ago
my-default:latest 2bb4cc1b3660 9.6 GB 3 days ago
gemma4:e4b c6eb396dbd59 9.6 GB 3 days ago

hf.co/unsloth/Qwen3-14B-GGUF:Q4_K_M 모델을 위한 모델 파일

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Modelfile
FROM hf.co/unsloth/Qwen3-14B-GGUF:Q4_K_M
#FROM ./DeepSeek-V4-Flash-Q4_K_M.gguf # 파일명 경로

# 한국어 및 코딩 최적화 설정
SYSTEM """
You are an expert AI developer.
Please provide all explanations and communication in Korean (한국어).
Technical terms and code can remain in English.
"""

# 3080 Ti(12GB) 최적화 파라미터
PARAMETER num_ctx 8192
PARAMETER num_gpu 99

ollama create qwen-7b-32k -f ~/Work/Modelfile

모델의 파라미터 확인

다운 받은 모델의 세부 파라미터를 확인할 수 있다. 이 정보를 모델 파일로 리다이렉트해서 편집해 사용할 수 있다.

1
ollama show qwen3-14b-coding --modelfile > Modelfile

ollama 모델 빌드

1
2
ollama create ds-v4 -f Modelfile
ollama run ds-v4
1
2
3
4
5
6
7
8
9
10
11
12
FROM gemma4:8b
PARAMETER num_ctx 32768
PARAMETER num_gpu -1

# 시스템 프롬프트를 명확하게 전달하기 위한 템플릿 추가
TEMPLATE """{{ if .System }}<|im_start|>system
{{ .System }}<|im_end|>
{{ end }}{{ if .Prompt }}<|im_start|>user
{{ .Prompt }}<|im_end|>
{{ end }}<|im_start|>assistant
"""
SYSTEM """You are an expert AI developer. 반드시 모든 설명과 대화는 한국어(Korean)로만 하세요. 기술 용어와 코드만 영어를 사용하세요. Use step-by-step reasoning for complex logic."""

성능 개선ㅁ

Gemma 2 9B(또는 최신 버전인 Gemma 4 계열) 모델은 구글 특유의 아키텍처 덕분에 비슷한 파라미터 대비 성능이 매우 뛰어납니다. RTX 4060 환경에서 이 모델의 잠재력을 끝까지 끌어올리기 위한 고급 최적화 전략을 정리해 드립니다.


1. 전용 퀀타이징(Quantization) 선택: Q4_K_M vs Q5_K_M

Ollama에서 기본으로 다운로드하면 보통 Q4_0 같은 일반 양자화 모델이 받아집니다. 하지만 RTX 4060(8GB VRAM)은 Q5_K_M까지도 충분히 수용 가능합니다.

  • 비교: Q4는 속도가 빠르지만 지능이 약간 깎이고, Q5는 지능을 거의 온전히 보존하면서 VRAM을 효율적으로 씁니다.
  • 방법: 직접 GGUF 파일을 구하거나, Ollama 라이브러리에서 태그를 확인하여 높은 비트의 모델을 선택하세요.
    1
    2
    ollama run gemma2:9b-instruct-q5_K_M

2. K-V Cache Quantization (VRAM 극단적 절약)

컨텍스트 길이를 늘렸을 때 속도가 느려지는 가장 큰 이유는 VRAM 부족입니다. Gemma 아키텍처는 컨텍스트가 길어질 때 메모리 점유가 가파른데, 이를 8비트나 4비트로 압축하면 해결됩니다.

  • WSL2 환경 변수 설정:
    1
    2
    3
    4
    5
    6
    # VRAM이 부족할 때 컨텍스트 메모리를 8비트로 압축 (지능 저하 거의 없음)
    export OLLAMA_KV_CACHE_TYPE=q8_0

    # 만약 32k 이상을 쓰면서 모델이 터진다면 4비트로 설정
    # export OLLAMA_KV_CACHE_TYPE=q4_0

설정 후 sudo systemctl restart ollama로 재시작하세요.

3. Flash Attention 활성화 (RTX 40 시리즈 필수)

RTX 4060은 Ada Lovelace 아키텍처로, Flash Attention 기능을 지원합니다. 이 기능을 켜면 긴 문장을 처리할 때 계산 효율이 기하급수적으로 좋아집니다.

  • 설정 방법:
    1
    2
    export OLLAMA_FLASH_ATTENTION=1

이 옵션을 켜면 토큰 생성 속도(Tokens Per Second)가 특히 긴 대화에서 눈에 띄게 개선됩니다.

4. GPU Layers 강제 할당 (num_gpu)

Gemma 모델 실행 시 일부 연산이 CPU로 넘어가면 병목 현상이 발생합니다. RTX 4060의 8GB VRAM은 Gemma 9B급 모델을 100% GPU에 올리기에 아주 약간 빠듯할 수 있습니다(컨텍스트 32k 기준).

이때 Modelfile에서 레이어 수를 강제로 지정하여 최적의 지점을 찾아야 합니다.

  • Modelfile 최적화 예시:
    1
    2
    3
    4
    5
    FROM gemma2:9b
    PARAMETER num_ctx 16384 # 32k가 무겁다면 16k로 타협하되 속도를 챙깁니다.
    PARAMETER num_gpu 42 # Gemma 2 9B의 전체 레이어를 GPU에 고정
    PARAMETER repeat_penalty 1.1

5. 시스템 메모리 스왑 및 오버헤드 제거

WSL2는 기본적으로 Windows RAM의 50%만 가져다 씁니다. 만약 모델이 GPU에서 넘쳐서 RAM을 써야 하는 상황(Fallback)이 오면 성능이 급락합니다.

  • .wslconfig 설정 (Windows 사용자 폴더 아래):

    1
    2
    3
    4
    [wsl2]
    memory=12GB # 전체 16GB RAM 기준, WSL에 더 많은 메모리 할당
    processors=8

  • 성능 모드: 노트북이라면 전원 케이블을 연결하고, Windows 설정에서 ‘최고 성능 모드’를 선택하세요. GPU 클럭이 고정되어야 추론 속도가 안정적입니다.


💡 요약: 무엇부터 해야 할까요?

  1. OLLAMA_FLASH_ATTENTION=1 설정 (가장 체감이 큽니다).
  2. OLLAMA_KV_CACHE_TYPE=q8_0 설정 (VRAM 부족으로 인한 렉 방지).
  3. 컨텍스트가 32k에서 너무 느리다면 16k로 낮추는 대신 모델 지능을 위해 Q5_K_M 양자화를 사용하세요.

현재 이 설정을 적용한 뒤 대화 속도가 초당 몇 토큰 정도 나오나요? 만약 nvidia-smi에서 VRAM이 7.5GB 이상 점유 중이라면 컨텍스트를 소폭 줄이는 것이 성능에 더 유리할 수 있습니다.


다음은 소스 분석에 대한 ollama 로그 기록이야 여기서 token 생산 성능을 높일 수 있는 팁이 없을까?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
5월 30 18:54:01 goyangi2 ollama[165]: time=2026-05-30T18:54:01.148+09:00 level=INFO source=server.go:771 msg="loading model" "model layers"=36 requested=-1
 5월 30 18:54:01 goyangi2 ollama[165]: time=2026-05-30T18:54:01.149+09:00 level=INFO source=runner.go:1290 msg=load request="{Operation:fit LoraPath:[] Parallel:1 BatchSize:512 FlashAttention:Enabled KvSize:16384 KvCacheType: NumThreads:8 GPULayers:36[ID:GPU-68892d1c-00e4-6f5b-d95b-4a5c8c1fc236 Layers:36(0..35)] MultiUserCache:false ProjectorPath: MainGPU:0 UseMmap:false}"
 5월 30 18:54:01 goyangi2 ollama[165]: time=2026-05-30T18:54:01.199+09:00 level=INFO source=model.go:97 msg="gemma4: token IDs" image=255999 image_end=258882 audio=256000 audio_end=258883
 5월 30 18:54:01 goyangi2 ollama[165]: time=2026-05-30T18:54:01.255+09:00 level=INFO source=runner.go:1290 msg=load request="{Operation:alloc LoraPath:[] Parallel:1 BatchSize:512 FlashAttention:Enabled KvSize:16384 KvCacheType: NumThreads:8 GPULayers:36[ID:GPU-68892d1c-00e4-6f5b-d95b-4a5c8c1fc236 Layers:36(0..35)] MultiUserCache:false ProjectorPath: MainGPU:0 UseMmap:false}"
 5월 30 18:54:01 goyangi2 ollama[165]: time=2026-05-30T18:54:01.314+09:00 level=INFO source=model.go:97 msg="gemma4: token IDs" image=255999 image_end=258882 audio=256000 audio_end=258883
 5월 30 18:54:01 goyangi2 ollama[165]: time=2026-05-30T18:54:01.489+09:00 level=INFO source=runner.go:1290 msg=load request="{Operation:commit LoraPath:[] Parallel:1 BatchSize:512 FlashAttention:Enabled KvSize:16384 KvCacheType: NumThreads:8 GPULayers:36[ID:GPU-68892d1c-00e4-6f5b-d95b-4a5c8c1fc236 Layers:36(0..35)] MultiUserCache:false ProjectorPath: MainGPU:0 UseMmap:false}"
 5월 30 18:54:01 goyangi2 ollama[165]: time=2026-05-30T18:54:01.489+09:00 level=INFO source=ggml.go:482 msg="offloading 35 repeating layers to GPU"
 5월 30 18:54:01 goyangi2 ollama[165]: time=2026-05-30T18:54:01.489+09:00 level=INFO source=ggml.go:489 msg="offloading output layer to GPU"
 5월 30 18:54:01 goyangi2 ollama[165]: time=2026-05-30T18:54:01.489+09:00 level=INFO source=ggml.go:494 msg="offloaded 36/36 layers to GPU"
 5월 30 18:54:01 goyangi2 ollama[165]: time=2026-05-30T18:54:01.489+09:00 level=INFO source=device.go:240 msg="model weights" device=CUDA0 size="3.1 GiB"
 5월 30 18:54:01 goyangi2 ollama[165]: time=2026-05-30T18:54:01.489+09:00 level=INFO source=device.go:245 msg="model weights" device=CPU size="264.0 MiB"
 5월 30 18:54:01 goyangi2 ollama[165]: time=2026-05-30T18:54:01.489+09:00 level=INFO source=device.go:251 msg="kv cache" device=CUDA0 size="150.0 MiB"
 5월 30 18:54:01 goyangi2 ollama[165]: time=2026-05-30T18:54:01.489+09:00 level=INFO source=device.go:262 msg="compute graph" device=CUDA0 size="173.5 MiB"
 5월 30 18:54:01 goyangi2 ollama[165]: time=2026-05-30T18:54:01.489+09:00 level=INFO source=device.go:267 msg="compute graph" device=CPU size="1.5 GiB"
 5월 30 18:54:01 goyangi2 ollama[165]: time=2026-05-30T18:54:01.489+09:00 level=INFO source=device.go:272 msg="total memory" size="5.2 GiB"
 5월 30 18:54:01 goyangi2 ollama[165]: time=2026-05-30T18:54:01.489+09:00 level=INFO source=sched.go:561 msg="loaded runners" count=1
 5월 30 18:54:01 goyangi2 ollama[165]: time=2026-05-30T18:54:01.489+09:00 level=INFO source=server.go:1364 msg="waiting for llama runner to start responding"
 5월 30 18:54:01 goyangi2 ollama[165]: time=2026-05-30T18:54:01.489+09:00 level=INFO source=server.go:1398 msg="waiting for server to become available" status="llm server loading model"
 5월 30 18:54:05 goyangi2 ollama[165]: time=2026-05-30T18:54:05.254+09:00 level=INFO source=server.go:1402 msg="llama runner started in 10.42 seconds"
 5월 30 18:54:05 goyangi2 ollama[165]: time=2026-05-30T18:54:05.435+09:00 level=WARN source=vocabulary.go:49 msg="adding bos token to prompt which already has it" id=[2]

ollama: claude code 실행

모델 선택: https://ollama.com/library/qwen2.5-coder

1
ollama launch claude --model qwen2.5-coder:7b
1
ollama launch claude --model qwen2.5-coder:14b

ollama launch claude –model gemma4-e4b-32k

nbconvert 사용

nbconvert은 jupyter notebook 파일을 markdown 파일 혹은 html 파일로 변환해주는 프로그램입니다.

설치

nbconvert 를 설치 한다.

1
2
3
4
5
# pip을 통해 nbconvert 설치
(env)$ pip install nbconvert

# conda를 통해 nbconvert 설치
(env)$ conda install nbconvert

사용

원하는 포맷을 --to 에 지정해서 변환한다, 지원되는 포맷은 다음 같다

  • HTML, LaTeX, PDF,WebPDF, Reveal.js HTML slideshow,
  • Markdown, Ascii, reStructuredText,executable script,notebook.

다음 같이 사용한다.

1
jupyter nbconvert --to FORMAT notebook.ipynb

nbconvert 로 markdown 변환 명령은 다음의 두가지 결과물을 생성한.

  • notebook.md : markdown 파일
  • notebook_files : markdown 파일에 포함되어 있는 모든 이미지를 모아놓은 폴더
1
2
3
(env)$ jupyter nbconvert notebook.ipynb
(env)$ ls
notebook.ipynb notebook.html notebook_files/

예를 들어 My_NOTEBOOK.ipynb 라는 jupyter notebook 파일을 markdown 파일로 변환한다면

1
(env)$ jupyter nbconvert --to markdown My_NOTEBOOK.ipynb

pyenv-doctor

pyenv 에 doctor 명령이 생겼다.

  • pyenv 설치 구성을 검증한다.
  • python 버전을 빌드하기 위한 개발 도구들

doctor 명령을 사용하려면 시스템에 개발도구와 빌드도구가 설치되어야 한다.

준비

pyenv 의 시스템 빌드환경에 필요한 도구를 설치가 필요하다.

Ubuntu/Linux

1
2
3
sudo apt update; sudo apt install build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev curl git \
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev

macOS

1
brew install openssl readline sqlite3 xz zlib tcl-tk@8 libb2

pyenv doctor 사용

1
2
3
4
5
$ pyenv doctor
Cloning /home/USER/.pyenv/plugins/pyenv-doctor/bin/.....
Installing python-pyenv-doctor...
Installed python-pyenv-doctor to /tmp/pyenv-doctor.20250327094025.5063/prefix
Congratulations! You are ready to build pythons!

기타

시스템에 빌드 도구가 설치되지 않으면 doctor 명령을 실행하면 다양한 에러를 낸다.

1
2
3
4
5
6
7
$ pyenv doctor
...
...
configure: error: GNU readline is not installed.
Problem(s) detected while checking system.

See https://github.com/pyenv/pyenv/wiki/Common-build-problems for known solutions.

jupyterlab - kernel 관리

Jupyter-lab 의 kernel 은 Jupyterlab 과 실행 환경과 직간접으로 연결을 해준다.

ipykernel 은 jupyter에 대해서 iPython을 제공한다.

ipython은 jupyterlab에 kernel을 통해서 python 혹은 virtualenv 의 개발환경을 제공한다.

kernel

jupyter-lab 을 실행하면 커널 launcher 화면에 kernel이 출력된다.

실행중인 커널은 사이트 바에서 확인 가능하다.

jupyter 명령으로 커널을 관리할 수 있다.

jupyter 명령

jupyter 명령에서 kernels 를 생성, 제거 관리를 할 수 있다.

현재 kernel 목록을 확인 가능하다.

1
2
$ jupyter kernelspec list
python3 /home/user/.pyenv/versions/MyEnv/share/jupyter/kernels/python3

새 kernel 생성성

가상환경 TestEnv 가 있다고 가정한다.

TestEnv 의 python 환경을 jupyterlab 에서 사용하려면

해당 가상환경을 jupyterlab 커널에서 사용하게 하려면 커널을 생성해 주어야 한다.

그러기 위해서 ipykernel 이 필요하다

1
pip install ipykernel

ipykernel 로 새 kernel 생성:

1
python -m ipykernel install --name {MACHINE_NAME} --display-name "{DISPLAY_NAME}" --user

다음 명령에서 --user을 사용하면 사용자의 ~.local/share 공간에 커널이 추가 되고 사용자의 jupyterlab 에서 모두 사용할 수 있다.

1
2
$ python -m ipykernel install --name testenv_kernel --display-name "Test Env" --user
Installed kernelspec testenv_kernel in /home/user/.local/share/jupyter/kernels/testenv_kernel

kernelspec 으로 확인 할 수 있고,

1
2
3
4
5
~$ jupyter kernelspec list
Available kernels:
python3 /home/qkboo/.pyenv/versions/3.12.8/envs/TestEnv/share/jupyter/kernels/python3
testenv_kernel /home/qkboo/.local/share/jupyter/kernels/testenv_kernel
(TestEnv) qkboo:~$

Jupyterlab 의 launcher 화면에도 새 커널을 확인할 수 있다.

kernel 제거

kernelspec uninstall 명령을 사용해서 사용자 커널을 제거할 수 있다.

1
jupyter kernelspec uninstall {KERNEL_NAME}

testenv_kernel 을 삭제해 보자

1
2
3
4
5
jupyter kernelspec uninstall testenv_kernel
Kernel specs to remove:
testenv_kernel /home/user/.local/share/jupyter/kernels/testenv_kernel
Remove 1 kernel specs [y/N]: y
Removed /home/user/.local/share/jupyter/kernels/testenv_kernel

— 참고 —

  1. https://docs.posit.co/ide/server-pro/user/jupyter-lab/guide/jupyter-kernel-management.html

mamba / micromamba 요약 정리

mamba 와 conda 는 서로 교체 가능한 파이썬 패키지 매니저이다.

mamba는 conda와 같은 사용방법과 동일한 환경을 이어받은 패키지 관리자 이다. conda & mamba 명령을 서로 거의 동일하게 사용할 수 있다. conda 의 패키지 채널을 그대로 사용할 수 있다.

1
2
3
mamba install ...
mamba create -n ... -c ... ...
mamba list

여기서는 micromamba를 사용해보려고 한다.

micromamba 는 mamba의 소규모 버전으로 독립적 실행 파일이다. 다만 mamba 와 micromamba는 환경 구성이 좀 다르다. micromamba는 mamba와 다르게 MAMBA_ROOT_PREFIX 환경 변수를 기준으로 패키지 관리가 시작되고 환경이 생성된다.

  1. 설치
  2. micromamba 사용
  3. 가상환경 사용
  4. Repoquery 명령
  5. Uninstall
  6. 참고

1. micromamba 설치

https://mamba.readthedocs.io/en/latest/installation/micromamba-installation.html

Linux, macOS, or Git Bash on Windows install with:

1
"${SHELL}" <(curl -L micro.mamba.pm/install.sh)

Windows 에서 설치

Windows 의 PowerShell에서 Execution-policy 를 지정해야 한다.

  1. PowerShell을 관리자로 연다
1
2
PS> Get-ExecutionPolicy
Restricted
  1. Set-ExecutionPolicy로 RemoteSigned 혹은 Unrestricted 로 지정한다.
1
PS> Set-ExecutionPolicy RemoteSigned
  1. 그리고 다음 스크립을 일반 PowerShell에서 실행한다
1
PS> Invoke-Expression ((Invoke-WebRequest -Uri https://micro.mamba.pm/install.ps1).Content)

설치를 진행한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
PS> Invoke-Expression ((Invoke-WebRequest -Uri https://micro.mamba.pm/install.ps1).Content)

Downloading micromamba from https://github.com/mamba-org/micromamba-releases/releases/latest/download/micromamba-win-64
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 9280k 100 9280k 0 0 3355k 0 0:00:02 0:00:02 --:--:-- 10.8M

Installing micromamba to C:\Users\student\AppData\Local\micromamba

Adding C:\Users\student\AppData\Local\micromamba\micromamba.exe to PATH

Do you want to initialize micromamba for the shell activate command? (Y/n): y
Enter the path to the micromamba prefix (default: C:\Users\student\micromamba):
Initializing micromamba in C:\Users\student\micromamba
C:\Users\student\AppData\Local\micromamba\micromamba.exe
The following argument was not expected: -p
Run with --help for more information.

Update

1
PS> micromamba self-update

특정 버전으로 업데이트도 가능하다.

1
PS> micromamba self-update --version 1.4.6

micromamba 도움말.

1
PS> micromamba --help

2. micromamba 사용

micromamba의 가상환경은 micromamba activate /path/to/env 같이 활성화 시키는데, MAMBA_ROOT_PREFIX 환경변수를 기준으로 micromamba activate env 같이 사용할 수 있다.

현재 사용할 수 있는 환경을 출력.

1
2
3
4
5
PS> micromamba env list
Name Active Path
--------------------------------------------------------------
base C:\Users\student\micromamba
C:\Users\student\miniconda3\envs\myenv

micromamba 명령으로 대부분의 conda 명령을 동일하게 실행할 수 있다.

1
2
3
4
5
6
7
8
9
10
micromamba info                          # 현재 micromamba 환경정보

# 설치한 패키지 목록
micromamba list ananconda # Anaconda 정보
micromamba list python # python 패키지 정보

# upgrade
micromamba update pip # pip upgrade
micromamba update pip=25.0 # pip upgrade to 25.0
micromamba update conda # conda upgrade

3. 가상환경 사용

-n 옵션으로 가상환경을 지정하고 생성/수정/삭제를 할 수 있고, 더불어 패키지를 함께 관리할 수 있다.

가상환경 생성

가상환경과 패키지를 함께 설치한다.

1
PS> mamba create -n myenv <list of packages>

가상환경에 python 버전을 지정할 수 있다.

1
PS> micromamba create -n myenv python=3.12

가상환경에 설치 채널을 지정해 설치할 수 있다. 아래는 conda-forge 채널 이용

1
PS> micromamba create -n myenv jupyterlab -c conda-forge python=3.12
1
2
# 가상환경 목록
PS> micromamba env list

가상환경 활성화

가상환경은 가상환경 이름을 주어 활성화 한다.

1
2
PS> micromamba activate myenv
(myenv) PS C:\Users\student>

혹은 가상환경이 있는 위치의 절대경로를 주어 활성화 할 수 있다.

1
PS> micromamba activate /path/to/myenv

run 명령은 가상환경을 사용해서 특정 스크립트/명령를 직접 실행할 수 있다.

1
PS> micromamba run -n myenv mycommand

가상환경 myenv 의 서버 목록을 출력

1
2
3
4
5
(myenv) PS> micromamba run -n myenv jupyter server list
Currently running servers:
http://localhost:8888/?token=317c9380f9c3ed4ab6f836a7ffbc789497728820e9c60f47 :: D:\Jupyter_Hub
http://localhost:8585/ :: D:\Jupyter_Hub
http://desktop-goyangi:8686/ :: D:\Jupyter_Hub

사용중인 가상환경 비활성화

1
2
(myenv) PS> micromamba deactivate
PS>

모듈/패키지 설치

micromamba 명령을 사용해 모듈과 패키지를 설치 채널을 지정해서 설치할 수 있다.

활성화 myenv 가상환경에서 matplotlib 패키지를 설치한다.

1
2
3
4
5
6
7
(myenv) PS>micromamba install matplotlib -c conda-forge
Pinned packages:
- python=3.12
Transaction
Prefix: C:\Users\student\micromamba\envs\myenv
...

비활성 상태에서 myenv 가상환경에 패키지를 설치한다.

1
2
3
4
5
6
PS> micromamba -n myenv install matplotlib
Pinned packages:
- python=3.12

Transaction
Prefix: C:\Users\student\micromamba\envs\myenv

가상환경 업데이트

특정 가상환경을 모두 업데이트

1
micromamba update -n myenv --all

환경의 모든 패키지를 덥데이트 하려면

1
micromamba update --all

가상환경 제거

설치한 가상환경을 지운다

1
2
3
PS> micromamba env remove -n myenv --all
...
Proceed ([y]/n)? y

4. Repoquery 명령

mamba 는 새로운 패키지 검색 명령으로 repoquery 명령을 선보이고 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 설치 가능한 모든 python 패키지 목록
$ micromamba repoquery search python

# 설치 가능한 python=버전 패키지 목록
$ micromamba repoquery search "python>=3.11"

# 설치 가능한 jupyterlab 버전 패키지 목록
$ micromamba repoquery search "jupyterlab>=4.0"


# 현재 환경의 jupyterlab 에 연관된 의존성 패키지 목록
$ micromamba repoquery depends jupyterlab

# 현재 환경의 jupyterlab 에 연관된 모든 의존성 세부 목록
$ micromamba repoquery depends jupyterlab --recursive

패키지 연관 의존성을 트리형식으로 출력할 수 있다.

1
2
3
4
5
6
7
8
# 현재 환경의 jupyterlab 에 연관된 의존성 패키지의 트리 목록
$ micromamba repoquery depends -t jupyterlab
jupyterlab[4.3.4]
├─ jupyter-lsp[2.2.0]
│ ├─ python already visited
│ └─ jupyter_server[2.15.0]
│ ├─ python already visited

And you can ask for the inverse, which packages depend on some other package (e.g. ipython) using whoneeds.

1
2
3
4
5
6
7
8
$ micromamba repoquery whoneeds ipython

Name Version Build Depends Channel
-------------------------------------------------------------------
jupyter_console 6.4.3 pyhd3eb1b0_0 ipython pkgs/main
ipykernel 6.9.1 py39haa95532_0 ipython >=7.23.1 pkgs/main
ipywidgets 7.6.5 pyhd3eb1b0_1 ipython >=4.0.0 pkgs/main
With the -t,--tree flag, you can get the same information in a tree.

트리 형식 출력

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ mamba repoquery whoneeds -t ipython

ipython[8.2.0]
├─ jupyter_console[6.4.3]
│ └─ jupyter[1.0.0]
├─ ipykernel[6.9.1]
│ ├─ notebook[6.4.8]
│ │ ├─ widgetsnbextension[3.5.2]
│ │ │ └─ ipywidgets[7.6.5]
│ │ │ └─ jupyter already visited
│ │ └─ jupyter already visited
│ ├─ jupyter_console already visited
│ ├─ ipywidgets already visited
│ ├─ jupyter already visited
│ └─ qtconsole[5.3.0]
│ └─ jupyter already visited
└─ ipywidgets already visited

5. Uninstall, Windows

Micromamba는 Windows 11에서 다음과 같은 방법으로 삭제할 수 있습니다.

  1. micromamba 설치 디렉토리 삭제:

micromamba가 설치된 디렉토리를 찾습니다. 일반적으로 C:\Users<사용자 이름>.local\bin 또는 C:\micromamba에 설치됩니다.
해당 디렉토리를 삭제합니다.

  1. 환경 변수에서 micromamba 경로 제거:

Windows 검색 창에서 “환경 변수”를 검색하고 “시스템 환경 변수 편집”을 엽니다.
“시스템 속성” 창에서 “환경 변수” 버튼을 클릭합니다.
“시스템 변수” 섹션에서 “Path” 변수를 선택하고 “편집” 버튼을 클릭합니다.
micromamba가 설치된 디렉토리 경로가 있는지 확인하고, 있다면 해당 경로를 삭제합니다.
“확인” 버튼을 클릭하여 변경 사항을 저장합니다.

  1. micromamba 관련 파일 삭제:

C:\Users<사용자 이름>.condarc 파일을 삭제합니다. (존재하는 경우)
C:\Users<사용자 이름>.mambarc 파일을 삭제합니다. (존재하는 경우)

C:\Users<사용자 이름>\AppData\Local\micromamba (존재하는 경우)

  1. (선택 사항) micromamba 설치 시 생성된 바로가기 삭제:

micromamba 설치 시 생성된 바로가기가 있다면 삭제합니다.

  1. (선택 사항) micromamba와 관련된 가상 환경 삭제:

micromamba를 사용하여 생성한 가상 환경이 있다면 해당 디렉토리를 삭제합니다. 가상 환경은 일반적으로 C:\Users<사용자 이름>.micromamba\envs 디렉토리에 저장됩니다.


참고

Python - 문서화 도구 Sphinx

Sphinx 는 python의 대표적인 문서화 도구로 reStructedText 또는 Markdown 문서를 HTML, pdf, man page 등의 결과물로 생성할 수 있다.

sphinx 설치

sphinx 는 python 환경에서 실행이 된다. 설치는 python 환경 혹은 OS 환경에 직접 설치하는 방법이 있다. 파이썬 가상환경을 권장한다.

https://www.sphinx-doc.org/en/master/usage/installation.html

- Python 환경에 설치

python 환경 혹은 python 가상환경 (venv, virtualenv 등)에 설치

pip

1
pip install sphinx

Anaconda

1
conda install sphinx

- 시스템에 직접 설치

각 OS 의 SW 로 설치한다면 package 관리자를 사용해 설치한다.

Debian/Ubuntu

1
apt install python3-sphinx

RHEL, CentOS

1
yum install python-sphinx

macOS / home-brew

1
brew install sphinx-doc

Pandas - Pivot, Stack, Unstack, Melt

Pandas 에서 2차원 data를 Stack, unstack, melt 를 이용해 복합 인덱스를 사용할 수 있고 Pivot 을 이용해 특정 데이터 중심의 2차원 데이터로 생성할 수 있다.

  1. Pivot
  2. Stack & Unstack
  3. Melt
1
2
import pandas as pd
import numpy as np

2차원 테이블

행과 열로 구성된 데이터 집합

1
2
3
4
5
6
7
df = pd.DataFrame(
{'foo' : ['One','One','One','Two','Two','Two'],
'bar': ['A','B','C','A','B','C'],
'baz': [1,2,3,4,5,6] ,
'zoo': ['x','y','z','q','w','t']}
)
df

foo bar baz zoo
0 One A 1 x
1 One B 2 y
2 One C 3 z
3 Two A 4 q
4 Two B 5 w
5 Two C 6 t

Pivot

피봇/피봇 테이블은 2차원 데이터 열에서 공통된 부분을 중심으로 새 테이블 집합을 형성하게 해준다. 피봇은 index, columns, values 라는 이름을 가진 세 가지 parameter를 취한다. 이러한 각 파라미터의 값으로 원래 표에 열 이름을 지정해야 한다.

foo, bar, baz, zoo 컬럼 중에서 foo 에 대해서 정리를 하고 bar 를 컬럼으로 지정하면 아래와 같다.

1
2
df_pivot = df.pivot_table(index='foo', columns='bar', values='baz')
df_pivot

bar A B C
foo
One 1 2 3
Two 4 5 6

ex) nba 데이터를 포지션의 연령별 연봉 테이블로 전환

1
2
dfnba = pd.read_csv('../data/nba.csv')
dfnba

Name Team Number Position Age Height Weight College Salary
0 Avery Bradley Boston Celtics 0.0 PG 25.0 6-2 180.0 Texas 7730337.0
1 Jae Crowder Boston Celtics 99.0 SF 25.0 6-6 235.0 Marquette 6796117.0
2 John Holland Boston Celtics 30.0 SG 27.0 6-5 205.0 Boston University NaN
3 R.J. Hunter Boston Celtics 28.0 SG 22.0 6-5 185.0 Georgia State 1148640.0
4 Jonas Jerebko Boston Celtics 8.0 PF 29.0 6-10 231.0 NaN 5000000.0
... ... ... ... ... ... ... ... ... ...
453 Shelvin Mack Utah Jazz 8.0 PG 26.0 6-3 203.0 Butler 2433333.0
454 Raul Neto Utah Jazz 25.0 PG 24.0 6-1 179.0 NaN 900000.0
455 Tibor Pleiss Utah Jazz 21.0 C 26.0 7-3 256.0 NaN 2900000.0
456 Jeff Withey Utah Jazz 24.0 C 26.0 7-0 231.0 Kansas 947276.0
457 NaN NaN NaN NaN NaN NaN NaN NaN NaN

458 rows × 9 columns

1
pd.options.display.float_format = "{:,.2f}".format

컬럼의 데이터에 공통된 모습이 많이 보인다. 이 중에서 포지션을 기준으로 나이에 따른 연봉을 본다고 가정하면 포지션을 인덱스로하고 나이를 컬럼으로 지정하면 아래와 같다.

1
2
# 포지션의 연령별 연봉 테이블
dfnba.pivot_table(index='Position', columns='Age', values='Salary')

Age 19.00 20.00 21.00 22.00 23.00 24.00 25.00 26.00 27.00 28.00 ... 31.00 32.00 33.00 34.00 35.00 36.00 37.00 38.00 39.00 40.00
Position
C NaN 5,143,140.00 1,571,000.00 3,476,698.20 2,121,999.50 4,532,003.33 10,881,995.00 3,041,850.82 5,004,260.50 7,635,761.83 ... 10,338,218.00 8,208,695.50 9,500,000.00 6,258,000.00 7,448,760.00 947,276.00 NaN 222,888.00 NaN 5,250,000.00
PF NaN 2,369,838.00 2,397,408.00 1,601,105.80 2,399,120.50 2,577,551.44 2,195,476.60 7,228,086.75 9,217,098.43 5,268,839.17 ... 5,323,787.00 14,346,365.00 2,630,241.40 6,469,277.50 2,624,593.50 2,877,470.00 6,666,667.00 NaN NaN 8,500,000.00
PG NaN 3,316,290.00 1,944,080.00 2,381,130.00 1,627,769.00 4,652,526.50 5,422,085.80 10,038,174.80 5,944,070.17 5,021,965.17 ... 7,467,596.40 4,082,425.33 2,226,179.67 8,395,104.00 NaN 2,170,465.00 NaN NaN 947,726.00 250,750.00
SF NaN 1,979,976.00 1,404,480.00 2,401,364.60 2,760,134.36 5,067,491.60 3,382,640.73 7,322,325.20 10,532,567.00 1,996,608.71 ... 10,960,320.25 9,720,195.75 NaN 261,894.00 947,276.00 1,721,559.75 25,000,000.00 3,376,000.00 NaN NaN
SG 1,930,440.00 1,749,840.00 2,215,710.43 2,055,241.00 1,388,251.18 3,205,720.53 1,782,834.89 9,872,690.29 4,815,524.62 6,354,000.00 ... 7,085,000.00 2,041,138.00 2,233,533.33 12,579,269.50 3,512,173.75 3,311,138.00 NaN 1,880,638.00 4,088,019.00 NaN

5 rows × 22 columns

Stack & Unstack

2차원 테이블은 행 과 열이 순차적 값으로 교차하게 되어 있다. 스택은 컬럼의 값을 아래-위로 배치를 시킨다고 상상이 된다. 그래서 스택과 언스택은 이렇게 생각된다.

  • stack : 2차원 컬럼의 내용을 수직방향으로 쌓는 구조, 즉 새로운 인덱스가 더해진다.
  • unstack : 인덱스 구성요소를 한 단계 컬럼으로 만들며 수평방향으로 쌓게 한다.

stack

pandas reshaping

1
2
3
4
5
6
7
df_single_level = pd.DataFrame(
[['Mostly cloudy', 10], ['Sunny', 12]],
index=['London', 'Oxford'],
columns=['Weather', 'Wind']
)
df_single_level

Weather Wind
London Mostly cloudy 10
Oxford Sunny 12

index와 weather, wind 라는 컬럼을 stack을 호출하면 weather-wind 관련 인덱스를 생성하고 데이터를 나열한다.

1
df_single_level.stack()
London  Weather    Mostly cloudy
        Wind                  10
Oxford  Weather            Sunny
        Wind                  12
dtype: object

다른 데이터를 살펴보자.

1
2
3
4
5
6
7
8
9
10
11
12
# MultiIndex
tuples = list(
zip(
*[
["bar", "bar", "baz", "baz", "foo", "foo", "qux", "qux"],
["one", "two", "one", "two", "one", "two", "one", "two"],
]
)
)
index = pd.MultiIndex.from_tuples(tuples, names=["first", "second"])
df = pd.DataFrame(np.random.randn(8, 2), index=index, columns=["A", "B"])
df

A B
first second
bar one -1.301694 -0.013259
two -0.197846 0.879890
baz one 0.718211 -0.739434
two -0.140217 0.071260
foo one -1.142268 -2.606413
two 1.119145 0.109402
qux one -0.504167 -1.703280
two 1.064976 1.011060

위 데이터는 stack()을 하면 A, B 컬럼이 MultiIndex 로 추가되며 A, B 컬럼 데이터 포인트가 배치된다.

1
df.stack()
first  second   
bar    one     A   -1.301694
               B   -0.013259
       two     A   -0.197846
               B    0.879890
baz    one     A    0.718211
               B   -0.739434
       two     A   -0.140217
               B    0.071260
foo    one     A   -1.142268
               B   -2.606413
       two     A    1.119145
               B    0.109402
qux    one     A   -0.504167
               B   -1.703280
       two     A    1.064976
               B    1.011060
dtype: float64
1
2
df2 = df[:4]
df2

A B
first second
bar one -1.301694 -0.013259
two -0.197846 0.879890
baz one 0.718211 -0.739434
two -0.140217 0.071260
1
2
stacked = df2.stack()
stacked
first  second   
bar    one     A   -1.301694
               B   -0.013259
       two     A   -0.197846
               B    0.879890
baz    one     A    0.718211
               B   -0.739434
       two     A   -0.140217
               B    0.071260
dtype: float64

Unstack

pandas reshaping

1
stacked
first  second   
bar    one     A   -1.301694
               B   -0.013259
       two     A   -0.197846
               B    0.879890
baz    one     A    0.718211
               B   -0.739434
       two     A   -0.140217
               B    0.071260
dtype: float64
1
stacked.unstack()

A B
first second
bar one -1.301694 -0.013259
two -0.197846 0.879890
baz one 0.718211 -0.739434
two -0.140217 0.071260

레벨을 지정

1
stacked.unstack(1)

second one two
first
bar A -1.301694 -0.197846
B -0.013259 0.879890
baz A 0.718211 -0.140217
B -0.739434 0.071260
1
stacked.unstack(2)

A B
first second
bar one -1.301694 -0.013259
two -0.197846 0.879890
baz one 0.718211 -0.739434
two -0.140217 0.071260
1

Melt

melt() 는 ID 변수를 기준으로 원래 데이터셋에 있던 여러개의 칼럼 이름을 ‘variable’ 칼럼에 위에서 아래로 길게 쌓아놓고, ‘value’ 칼럼에 ID와 variable에 해당하는 값을 넣어주는 식으로 데이터를 재구조화합니다.

1
2
3
4
5
6
7
8
9
cheese = pd.DataFrame(
{
"first": ["John", "Mary"],
"last": ["Doe", "Bo"],
"height": [5.5, 6.0],
"weight": [130, 150],
}
)
cheese

first last height weight
0 John Doe 5.50 130
1 Mary Bo 6.00 150
1
2
# colums중 height, weight 를 row 로 융합
cheese.melt(id_vars=['first','last']) # first, last 인덱스로 나머지 컬럼은 value 로 치환

first last variable value
0 John Doe height 5.50
1 Mary Bo height 6.00
2 John Doe weight 130.00
3 Mary Bo weight 150.00
1
cheese.melt(id_vars=['first','last'], value_name='quantity') 

first last variable quantity
0 John Doe height 5.50
1 Mary Bo height 6.00
2 John Doe weight 130.00
3 Mary Bo weight 150.00
1

참고

  1. pandas.DataFrame.stack

Pandas/Numpy 숫자의 출력 옵션 조정

numpy 와 pandas 에서 수를 출력할 때 형식, 크기 및 범위를 설정할 수 있다. 간단히 보면 아래 테이블 같이 형식을 바꿔준다.

column 변환 column
1e6 precision 1,000,000
1.1e-6 format 0.1

아래 요약한 옵션 방법을 사용해서 Numpy 와 Pandas에 있는 숫자를 출력할 때 표현방법, 표기법, 환률, 정밀도 등을 변경해 사용할 수 있다

numpy 출력 형식 변경

numpy 숫자 출력 형식 변경

numpy.set_printoptions 을 사용할 수 있다.

1
2
numpy.set_printoptions(precision=None, threshold=None, edgeitems=None, linewidth=None, suppress=None,
nanstr=None, infstr=None, formatter=None, sign=None, floatmode=None, *, legacy=None)

현재 출력형식 확인

np.get_printoptions() 으로 현재 상태를 출력할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
> np.get_printoptions()
{'edgeitems': 3,
'threshold': 1000,
'floatmode': 'maxprec',
'precision': 8,
'suppress': False,
'linewidth': 75,
'nanstr': 'nan',
'infstr': 'inf',
'sign': '-',
'formatter': None,
'legacy': False
}

Numpy 에서 실수 Float 의 출력 형식을 바꾸는 몇가지 사례를 보자

- formatter 이용

1
2
import numpy as np
np.set_printoptions(formatter={'float_kind': lambda x: "{0:0.3f}".format(x)})

- precision 이용

1
2
3
> np.set_printoptions(precision=4)
> np.array([1.123456789])
[1.1235]

- threshold 이용

개수가 많은 아이템을 출력할 때 요약해 출력할 수 있다.

1
2
3
> np.set_printoptions(threshold=5)
> np.arange(10)
array([0, 1, 2, ..., 7, 8, 9])

numpy.printoptions 사용

numpy.printoptions 를 with 구문과 함께 사용해 제한된 출력 조정을 할 수 있다.

출력시 printoptions 를 with 구문과 사용할 수 있다. set_printoptions 의 인자를 동일하게 적용할 수 있다

  • precision, threshold, edgeitems, linewidth, suppress, nanstr, infstr, formatter, sign, floatmode
1
numpy.printoptions(*args, **kwargs)[source]

소수점 출력 변경

1
2
3
4
5
6
> np.array([2.0]) / 3
array([0.66666667])


> with np.printoptions(precision=3):
> print( np.array([2.0]) / 3 )

pandas 숫자 출력 형식 변경

pandas에서 몇 가지 옵션을 바꾸는 방법을 정리해 보자. pandas의 옵션은 pd.options 를 사용한다.

pd.options.display

출력의 형태, 표기를 변경하는 것은 pd.options.display 아래에 있다. 여기서 사용할 수 있는 옵션은 describe_option() 으로 확인할 수 있다.

1
2
3
4
5
6
7
> pd.describe_option()
compute.use_bottleneck : bool
Use the bottleneck library to accelerate if it is installed,
the default is True
Valid values: False,True
[default: True] [currently: True]
...

- row, column 출력 개수 조정

  • pd.options.display.max_rows : 표를 출력할 때 최대 행 수입니다.
  • pd.options.display.min_rows : 표를 출력할 때 최소 행 수입니다.
1
2
3
4
5
import pandas as pd
> pd.options.display.max_rows
60
> pd.options.display.min_rows
10

min_row, max_row에 직접 대입하면 해당 옵션의 현재 값이 변경된다.

1
2
3
> pd.options.display.min_rows=100
> pd.options.display.min_rows
100

max_rows에 값을 입력하면 테이블의 최대 행수를 바꿀 수 있다.

이미지 참조 1

1
2
3
> pd.options.display.max_rows = 100
> pd.options.display.max_rows
100

- pd.get_option(), pd.set_option() 함수

pd.get_option() 함수를 이용해서 옵션인자에 대한 정보를 확인할 수 있다.

1
2
> pd.get_option('min_rows')
100

get_option은 옵션 이름의 일부만 일치해도 된다.

1
2
> pd.get_option('min_r')
100

max_rows 수를 설정한다. set_option도 일부만 일치해도 된다.

1
2
3
4
5
6
> pd.set_option('max_rows', 20)
> pd.options.display.max_rows
20
> pd.set_option('max_r', 50)
> pd.options.display.max_rows
50

- 컬럼의 폭 조정

display.max_colwidth 는 보통 50~70자 정도 정해져 있다. 컬럼에 표시되는 텍스트가 50자가 넘으면 ... 줄임 표시가 나타난다.

1
2
> pd.options.display.max_colwidth
50

- chop_threshold

chop_threshold 는 값의 크기 한계를 지정해서 이 값보다 작은 수는 모두 0으로 표시한다.

1
2
3
4
5
6
> pd.options.display.chop_threshold = 0.99
> pd.DataFrame({'x': [10, 1, 0.1]})
> print(x)
0 10.0
1 1.0
2 0.0

숫자 포매팅

다양한 사례는:

- float_format

float_format 는 실수 값을 출력시 소수점의 출력의 정밀도를 조정할 수 있다. 아래 람다 함수 lambda x: f'{x:.1f} 는 실수 x를 받아 소수점 첫째 자리까지 출력해 준다.

1
2
3
4
> pd.options.display.float_format = lambda x: f'{x:.1f}'
> pd.DataFrame({'x': [3.141592]})
x
0 3.1

또한 set_option 을 사용할 수 있다.

1
> pd.set_option('display.float_format', '{:.2f}'.foramt )

금액 단위에 사용하는 천단위 구분을 위해서 {:,.2f} 형식을 사용하면 화폐 단위를 추가하고 천단위 구분자를 추가해 주고 소수점 2자리수 정밀로를 지정한다.

1
2
3
4
5
> pd.set_option('display.float_format', '${:,.2f}'.format )
> pd.DataFrame({'x': [10000000.0, 34589234.4]})
x
0 $10,000,000.00
1 $34,589,234.40

- precision

실수의 소수점은 precision 로 과학적 표기법으로 변환할 자릿수를 지정한다. 아래와 같이 하면 소수점 셋째 자리 밑으로는 과학적 표기법으로 표시합니다.

1
2
3
4
> pd.options.display.precision = 3
> pd.DataFrame({'x': [0.5], 'y': [0.0005]})
x y
0 0.5 5.000e-04

과학적 표기법으로 3.000e-04는 3.000 이다. 자릿수가 아주 작거나 큰 수를 표기할 때 유용합니다.

- 설정 초기화 reset_option()

설정을 초기화할 때 사용한다.

1
2
3
4
# chop_threshold 옵션 초기화
pd.reset_option('display.chop_threshold')
# float_format 옵션 초기화
pd.reset_option('display.float_format')

- 옵션 설명 describe_option()

pd.describe_option(OPTIONS) 를 사용하면 해당 옵션에 대한 설명을 출력해 준다.

1
2
3
4
5
> pd.describe_option("max_rows")
display.max_rows : int
If max_rows is exceeded, switch to truncate view. Depending on
`large_repr`, objects are either centrally truncated or printed as
a summary view. 'None' value means unlimited.

참고

1: Try These Pandas Display Configurations

2: Pandas options

Python - 파이썬 프로젝트 패키징과 배포하기

파이썬에서 작업한 소스를 공개/비공개 배포하기 위해서 패키징을 하는 방법을 요약, 정리했다.

파이썬 모듈 배포하기

이 글은 setuptools, builds 그리고 PyPI 업로드를 위한 twine 를 사용하고 있다.

[핵심 용어]

  • PyPi, Python Package Index: 파이썬 사용자를 위한 오픈소스 패키지의 공개 저장소 일명 PyPi
  • PyPa, 파이썬 패키징 위원회: 표준 패키징 도구/메타 데이터/파일 형식 표준을 GitHub 와 Bitbucket 을 통해서 여러 패키징 도구, 문서, 이슈 추적기를 관리하고 있다.
  • distutils: 1998년/파이썬 표준 라이브러리 최초의 빌드 및 배포 시스템. 대부분 직접 사용이 단계적으로 폐지되고 있다.
    • distutils는 파이썬 3.10부터 deprecated, 3.12에서 삭제될 예정.
  • setuptools : 2004 공개/ distutils 의 드롭인(drop-in) 대체품. distutils 와 큰 차이는 다른 패키지에 대한 의존성을 선언할 수 있다.
  • [pyproject.toml]: 2016년 setuptools의 메타 파일 setup.py 의존성을 피하고자 독립한 빌드용 선언적 메타정보 파일.
  • wheel: distutils/setuptools 에 bdist_wheel 명령을 추가하는 프로젝트이다. 파이썬 라이브러리를 바이너리 확장을 포함/크로스 플랫폼 바이너리 패키징 형식 지원 (“휠”,”휠 파일”, PEP 427 정의).

도구 설치

setuptools 기반 배포도구 설치

1
python -m pip install setuptools wheel twine

파이썬 패키징

https://packaging.python.org/en/latest/tutorials/packaging-projects/ 내용을 요약, 정리, 보충한다.

프로젝트 생성

패키징 수행하면 별도의 가상환경을 생성해서 진행한다.

프로젝트를 패키징하는 과정을 위해서 packaging_tutorial 폴더 아래에 같은 구조를 갖는다.

1
2
3
4
5
packaging_tutorial/
└── src/
└── example_package_YOUR_USERNAME_HERE/
├── __init__.py
└── example.py
  • example_package_YOUR_USERNAME_HERE : 프로젝트 이름이고 중복하지 않게 한다.
  • __init__.py : 빈 파일로 폴더를 패키지로 인식하게 한다.
  • example.py : 모듈.

example.py 모듈 소스.

1
2
def add_one(number):
return number + 1

패키징용 파일 생성

배포를 위한 프로젝트의 구성을 위해 패키징에 필요한 파일을 추가한 구조는 아래 같다.

1
2
3
4
5
6
7
8
9
packaging_tutorial/
├── LICENSE
├── pyproject.toml
├── README.md
└── src/
│ └── example_package_YOUR_USERNAME_HERE/
│ ├── __init__.py
│ └── example.py
└── tests/
  • LICENSE : 라이센서 선언
  • pyproject.toml : 프로젝트 배포 프로젝트 생성에 사용하는 프론트엔드 빌드도구 pip, 백엔드 밸드도구 build
  • README.md
  • tests/ : 테스트 파일용 공간. Leave it empty for now.

패키징의 프론트엔드, 백엔드는 참조의 5번 항목을 살펴보자.

pyproject.toml 구성

보통 파일 내용은 아래 항목으로 구성한다. 이 파일은 TOML 형식의 구조를 따르고 있다. 여기에 대해서는 아래 참조 4번 항목 내용을 보기 바란다.

1
2
3
4
5
6
7
8
9
[build-system]
...

[project]
...

[project.urls]
...

빌드 도구를 명시하는 명세서 pyproject.toml에 setuptools 를 사용한 예이다.

1
2
3
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
  • requires : 빌드용 도구 지시.
  • build-backend : 프론트엔드 (pip)에서 빌드에 사용하는 백엔드 도구

다음은 Hatching 이란 빌드 도구를 사용한 예이다.

1
2
3
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

메타 정보를 포함한 간단한 pyproject.toml 구성 결과.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"

[project]
name = "example_package_YOUR_USERNAME_HERE"
version = "0.0.1"
authors = [
{ name="Example Author", email="author@example.com" },
]
description = "A small example package"
readme = "README.md"
requires-python = ">=3.7"
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
]

[project.urls]
"Homepage" = "https://github.com/pypa/sampleproject"
"Bug Tracker" = "https://github.com/pypa/sampleproject/issues"

자세한 메타 정보 내역은 프로젝트 메타정보 정의를 참조한다. 주요 메타 정보의 인자:

  • [project]:
    • requires-python : 패키지가 요구하는 최소 파이썬 버전 명시
    • classifiers: pip가 인지하는 패키지에 대한 정보

README.md / LICENSE 파일

README.md 파일에 패키지 모듈를 설명한다.

1
2
3
4
5
# Example Package

This is a simple example package. You can use
[Github-flavored Markdown](https://guides.github.com/features/mastering-markdown/)
to write your content.

LICENSE 파일에 저작권을 명시한다.

1
2
3
Copyright (c) 2018 The Python Packaging Authority

Permission is hereby granted, free of charge, to any person obtaining a copy

배포 묶음 생성하기

배포를 위한 build 도구를 설치한다.

1
python3 -m pip install --upgrade build

packaging_tutorial 폴더 아래 pyproject.toml 파일이 있는 위치에서 배포를 위한 build 명령으로 소스를 패키징을 한다.

build 를 수행하면 별도의 venv 가상환경을 생성해서 의존성에 명시된 setuptools 등을 설치하고 빌드를 진행한다.

1
2
3
4
5
6
7
> python3 -m build
* Creating venv isolated environment...
* Installing packages in isolated environment... (setuptools>=61.0)
...
...
removing build\bdist.win-amd64\wheel
Successfully built example_package_YOUR_USERNAME_HERE-0.0.1.tar.gz and example_package_YOUR_USERNAME_HERE-0.0.1-py3-none-any.whl

이 명령의 결과로 dist 폴더에 우리 프로젝트에 대한 배포용 패키징으로 소스 패키징 .gz 파일, built distribution 패키징 .whl 2개의 파일이 생성된다.

1
2
3
dist/
├── example_package_YOUR_USERNAME_HERE-0.0.1-py3-none-any.whl
└── example_package_YOUR_USERNAME_HERE-0.0.1.tar.gz

pip 로 wheeels 설치하기

pip 에서 built distribution 파일을 직접 설치할 수 있다. installing-from-wheels 참조.

다음은 우리 프로젝트의 wheel 패키징을 설치한다.

1
python -m pip install example_package_YOUR_USERNAME_HERE-0.0.1-py3-none-any.whl

혹은 provides_extras 메타 정보를 사용해 추가 설치를 한다면,

1
python -m pip install './somepackage-1.0-py2.py3-none-any.whl[my-extras]'

Upload

처음 PyPi 에 업로드를 하려면 아래 2가지 단계를 거쳐서 진행해 본다.

  1. https://test.pypi.org/account/register/ 에서 등록
    1. 실제 pypi 가 아닌 튜토리얼과 테스트를 위한 곳.
  2. PyPi 업로드를 완성하려면 PyPI API token 을 발급받아야 한다.
    1. https://test.pypi.org/manage/account/#api-tokens

PyPI에 업로드가 완료되면 pip 를 통해서 패키지를 설치할 수 있다. 업로드를 위해서 Twin 패키지를 설치하고 사용해야 한다.

1
python3 -m pip install --upgrade twine

twine 모듈을 사용해서 dist/ 아래의 모든 소스/휠 패키징 묶음을 업로드할 수 있다. 지금은 testpypi 에 업로드를 해보자.

1
python3 -m twine upload --repository testpypi dist/*
  • 업로드시 username은 __token__ 사용.
  • 패스워드는 발급받은 pypi- 으로 시작하는 token 값.

업로드 진행은 아래 같을 것이다.

1
2
3
4
5
6
7
Uploading distributions to https://test.pypi.org/legacy/
Enter your username: __token__
Uploading example_package_YOUR_USERNAME_HERE-0.0.1-py3-none-any.whl
100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.2/8.2 kB • 00:01 • ?
Uploading example_package_YOUR_USERNAME_HERE-0.0.1.tar.gz
100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 6.8/6.8 kB • 00:00 • ?

여기서 repository로 testpypi 를 지정했으므로 업로드한 결과는 다음 같이 확인할 수 있다.

  • https://test.pypi.org/project/example_package_YOUR_USERNAME_HERE

저장소에서 설치하기

위에 testpypi 에 업로드한 패키지를 설치하려면 아래 같이 --index-url 로 저장소를 지정해서 사용한다.

1
python3 -m pip install --index-url https://test.pypi.org/simple/ --no-deps example-package-YOUR-USERNAME-HERE

PyPI 에 업로드

마지막으로 실제 패키지를 PyPI에 업로드하려면 https://pypi.org 등록을 하고, 등록한 사용자 아이디를 사용하고 --repository 인자를 제외하고 업로드하면 된다.

1
python3 -m twine upload dist/*

통합 메타 정보로서 pyproject.toml 활용

테스트, 코드 포맷팅 등에 대한 정보로 활용한다. 대표적으로는 코드 포맷팅 도구인 black, 테스트용 프레임워크인 pytest 등이 pyproject.toml에 설정 값을 저장하고 있다 - 파이썬 패키징의 역사, blog

1
2
3
4
5
# pyproject.toml of black
[tool.black]
line-length = 88
target-version = ['py36', 'py37', 'py38']
include = '\.pyi?$'

다음

이후에 다른 빌드 도구들, 테스트 도구들을 다뤄보자.

참고

  1. 파이썬 모듈 배포하기, python.org
  2. Tool recommendations, python.org
    1. 주요 패키징에 필요한 도구 안내
  3. 파이썬 패키징의 역사, blog
  4. TOML의 이해와 기본 활용, itworld
  5. Python package의 build frontend 와 backend