2026년 4월 26일 일요일

Codex에서 Unity MCP 설치 in Windows VS Code

Unity로 작업을 하면서 현재까지는 Codex 만 사용했었는데, 이번에 MCP를 Unity 에서 설치해 봤습니다. 

CODEX 만으로도 지금껏 잘 사용해 왔지만, 명령을 내리면 원하는 것을 구현 할때나 오류가 발생하는 경우 처리를 지속적으로 대화로 풀어야 했습니다.

MCP를 이용하게 되면 CODEX가 직접 컴파일도 해볼 수 있고, 오류도 직접 처리가 가능합니다. 물론 좀 더 상세한 접근이 가능해집니다.

다만 토큰 소모가 좀 많은 것 같습니다.


Codex에서 Unity MCP 설치 in Windows VS Code

Unity MCP 설치



    • 서버 메뉴 진입(Tools > MCP Unity > Server Window)


    • Configure Codex CLI


    • VS Code 에서 프로젝트를 열어서 Codex 에 MCP 상태를 물어봄






2026년 4월 25일 토요일

Unity 에서 Font가 깨질때

Unity 에서 TextMeshPro 폰트가 깨지는 경우 Font Asset 도 여러번 재생성 해보고 했지만 해결 되지 않았습니다.

일반적으로 구글링 해보면 지원하지 charset의 경우 네모 사각형이 나오지만, 제가 발생한 현상은 한글이던 영문이던 모든 폰트가 삼각형 형태의 톱니 모양으로 나오는 증상이었습니다. Fallback으로 해당 폰트를 설정하면 정상으로 나와서 처음에는 어디 문제인지 판단하기 어려워서 URP, SRP 쪽도 확인해봤지만 결론은 TextMesh Pro를 재설치 함으로서 해결하였습니다.


2026년 4월 5일 일요일

OpenClaw에서 Discord 설정시

OpenClaw 에 Discord 연결시 반응이 없는 경우... 이것 때문에 한참 헤맸습니다.

특이한점이 '@' 붙여서 문의 할때는 아무런 답변이 없었는데, DM 으로 채팅시 최초 아래와 같이  Pairing code: 입력하라고 나타납니다.

이것도 최초에 한번만 나타나서 안되는 사유를 확인하기 어려웠습니다.


cmd line에서 아래와 같이 코드 입력 하면 됩니다.

openclaw pairing approve discord <CODE>

2026년 2월 22일 일요일

MacBook Air 13 M3 16GB ComfyUI 성능

 테스트한 PC의 SPEC입니다.


Text2Image 모델로 생성 시간을 측정 해보았습니다.

애니메이션 스타일 이미지 생성모델인 NetaYume Lumina 를 이용하였습니다. 아래 화면에서 제일 우측 하단 입니다.




1024*1024 크기로는 13분 16초
512*512 크기로는 2분 13초



다음으로는 Flux.2 [Klein] 4B 텍스트->이미지 모델입니다.







1024*1024 크기로는 15분 32초
512*512 크기로는 3분 36초


이미지 생성이 오래 걸려서 영상 생성은 시도해 보지 않았습니다.





Mac 처음 사용자, 폴더 이해와 iCloud Drive 폴더

1. 첫 출발은 Finder

윈도우의 탐색기와 비슷합니다. 좌측 하단에 파인더앱을 선택해서 실행을 합니다.



2. 데스크탑 폴더란

윈도우의 바탕 화면과 비슷한 개념으로 데스크탑 폴더에 들어 있는 항목은 로그인 시 홈화면 바탕화면에 나타납니다.

아래 그림에서는 desktopfolder 라는 폴더를 만들어서 넣어두었는데 우측에 나타나고 있습니다.



3. Machintosh HD

최상위 드라이브를 말합니다. 기본적으로 보이지 않으나 Finder의 설정의 하드 디스크 옵션으로 테스크탑에 보이게 할 수 있습니다. 개인적으로 보이게 하는것을 추천합니다.

해당 옵션을 선택하면 2번 화면 우측에 Machintosh HD 가 나타나며 더블 클릭하면 Finder의 경로가 최상단 경로가 나타나는 화면이 나타납니다.


4. iCloud Drive 동기화시

"데스트탑" 및 "문서" 폴더가 동기화 되고 계정 홈 폴더 아래에 있던 "데스트탑" 및 "문서" 폴더가 사라지고 iColud Drive 위치에서만 접근이 됩니다.

cmd line 명령으로 확인해보면 폴더가 사라진것은 아니고 보이지 않는 상태 됩니다.


5. 클라우드 백업이 되지 않는 폴더를 만들자

중요한 문서의 경우 문서 폴더에 만들어서 iCloud Drive에 백업하도록 만들고, 임시로 작업하거나 설치하는 어플의 iCloud Drive에 백업할 필요가 없는것들은 임의의 폴더에 저장 하도록 합니다. 임의의 폴더를 만들고 나서 꼭 즐겨 찾기에 등록(끌어다 놓기)하도록 합니다. 즐겨 찾기에 등록하지 않으면 그곳에 저장할때 루트부터 접근 할 수 있는 방법을 제공하지 않습니다.

 여기에서는 work 폴더를 계정 아래에 만들고 즐겨찾기에 추가하였고 색상도 변경하였습니다. (해당 폴더는 iCloud Drive 백업이 되지 않습니다.)



6. Machintosh HD 하위에 있는 폴더들

/Applications : 사용하는 앱들이 저장된 공간입니다. 

/Library : os 또는 시스템, 어플리케이션 프로그램들이 사용하는 각종 파일들이 여기에 있습니다. 

/System : os의 시스템 폴더입니다.

/Users : 유저별 디렉토리입니다. /Users/(사용자계정이름)/ 위치가 사용자의 홈이 되고 여기 위치에 데스크탑이나 문서, 그림, 다운로드, 동영상, 음악 같은 폴더가 존재합니다. (4번에 의해 데스크탑이나 문서 폴더는 안보일 수 있습니다.)



7. dmg 확장자 프로그램 설치 방법

파일명이 DMG(Disk Image) 파일은 macOS에서 주로 사용하는 가상 디스크 이미지 파일 형식으로,  파일을 더블 클릭하여 마운트한 후(마운트를 하게 되면 파인더의 외장 디스크 설정에 따라 우측에 마운트 포인트가 보이게 됨) 앱을 응용 프로그램 폴더로 드래그하여 설치합니다. 설치 후 삭제해도 무방합니다


바탕화면 우측에 나타나는 마운트 포인트들은 파일 > 추출로 마운트를 해제 할 수도 있습니다.



2026년 2월 21일 토요일

Mac 에서 ComfyUI 설치할때 폴더 설정, 그리고 ComfyUI 완전히 삭제 하는 방법

 Mac 을 처음 사용하다보니 윈도우와 다르게 뭔가 적응이 안되서 정리해 놓습니다.

ComfyUI 는 많은 모델과 체크포인트 데이터를 추가로 다운로드 하게 됩니다. 그런데 대부분의 Mac 사용자는 iCloud sync를 사용하고 있습니다.

그리고 ComfyUI 가 기본으로 문서(Documents)폴더 아래에 설치하고 있습니다. 그렇게 되면 클라우드 용량이 꽉차는 현상이 벌어집니다. 따라서 사용자 아래 iCloud와 sync 하지 않는 폴더를 만들고 해당 폴더 아래에 설치하기 바랍니다.

참고 work 폴더를 만들고 설치하는 과정


잘못 설치하였다면 삭제해야하는데

다음과 같은 과정으로 삭제를 하면 됩니다.


  1. 애플리케이션 삭제: 응용 프로그램(Applications) 폴더에서 ComfyUI (또는 ComfyUI 앱)를 찾아 휴지통으로 이동합니다.
  2. 관련 폴더 삭제 (중요): Finder에서 Shift + Command + G를 누르고 아래 경로들을 찾아 삭제합니다:
    • ~/Library/Application Support/ComfyUI/
    • ~/Library/Preferences/com.comfyui.plist (존재하는 경우)
    • ~/Library/Caches/com.comfyui/ (존재하는 경우)
    • 직접 설치한 경우: ComfyUI를 설치했던 폴더(예: Documents/ComfyUI) 자체를 삭제합니다.



2026년 1월 25일 일요일

text encoding classification

그새 많은 것들이 바뀐것 같습니다. 대부분의 글들은 GPT와 같은 LLM들을 많이 사용하게 되었고, 손으로 직접 적는 블로그들이 많이 사라진것 같습니다. 그동안 포스팅이 뜸했던 것도 비슷한 사유가 되겠습니다.
앞으로 글을 쓰면서 LLM을 이용한 부분에 대해서는 표기를 하도록 하겠습니다.

이번글은 주어지는 text들을 비지도 학습으로 분류하는 방법 입니다. 여러가지 방법이 있겠지만 GPT를 이용해서 이것저것 시도해 보았고 그중에 추천하는 방법에 대해서 샘플을 실행해서 동작하는 것을 보고 가져왔습니다. GPT에 묻더라도 장황하고, 몇단계로 질문은 해야 정리가 되고 결과물도 실제 테스트된 코드도 아니기 때문에 이글에서는 해당 내용들을 정리했다고 보면 됩니다.

다음 순서로 진행 됩니다.
문장 분리 → Sentence-BERT 문장 임베딩  → 문단 임베딩 (문장 평균)  → UMAP  → HDBSCAN
 → 클러스터 ID

입력 포맷입니다.

JSONL 예시 데이터

{"input":"오늘 날씨가 정말 좋다. 하늘이 맑아서 기분이 상쾌하다. 오랜만에 산책을 나갔다."} {"input":"비가 하루 종일 내렸다. 우산을 챙기지 않아서 옷이 다 젖었다. 날씨가 우울하다."} {"input":"기온이 갑자기 떨어졌다. 바람도 많이 불어서 체감 온도가 낮다."} {"input":"점심으로 김치찌개를 먹었다. 국물이 진하고 고기가 부드러웠다. 다음에는 또 오고 싶다."} {"input":"저녁에 친구들과 치킨을 시켜 먹었다. 양이 많고 바삭해서 만족스러웠다."} {"input":"이탈리안 레스토랑에 갔다. 파스타와 피자가 정말 맛있었다. 분위기도 좋았다."} {"input":"파이썬으로 머신러닝을 공부하고 있다. 데이터 전처리가 가장 어렵다. 그래도 재미있다."} {"input":"딥러닝 모델의 성능을 개선했다. 하이퍼파라미터 튜닝이 효과적이었다."} {"input":"자연어 처리를 위해 Sentence-BERT를 사용하고 있다. 임베딩 성능이 매우 좋다."} {"input":"주식 시장이 크게 하락했다. 투자 심리가 위축되고 있다. 당분간 변동성이 클 것 같다."} {"input":"비트코인 가격이 다시 상승했다. 가상자산 시장에 관심이 몰리고 있다."} {"input":"환율 변동이 심해지고 있다. 수입 기업들의 부담이 커지고 있다."} {"input":"The weather is really nice today. The sky is clear and blue. I decided to take a walk."} {"input":"It rained all day. I forgot my umbrella and got completely soaked."} {"input":"The temperature dropped suddenly. It feels much colder than yesterday."} {"input":"I had pasta for lunch. The sauce was rich and delicious. I would love to visit again."} {"input":"We ordered fried chicken for dinner. It was crispy and well seasoned."} {"input":"The restaurant had a great atmosphere. The food was amazing and fresh."} {"input":"I am studying machine learning with Python. Data preprocessing is harder than expected."} {"input":"The deep learning model achieved better accuracy. Hyperparameter tuning really helped."} {"input":"Sentence embeddings are useful for text clustering. SBERT works very well."} {"input":"The stock market dropped significantly today. Investors are getting nervous."} {"input":"Bitcoin prices are rising again. The crypto market is becoming volatile."} {"input":"Exchange rates are fluctuating rapidly. Global markets are reacting."} {"input":"오늘은 회의가 많았다. 프로젝트 일정에 대해 논의했다. 생각보다 시간이 오래 걸렸다."} {"input":"팀원들과 협업이 잘 되고 있다. 커뮤니케이션이 프로젝트 성공의 핵심이다."} {"input":"I had a meeting all morning. We discussed the project timeline in detail."} {"input":"Team collaboration is going well. Clear communication makes everything easier."} {"input":"파이썬으로 데이터 분석을 진행했다. 판다스와 넘파이를 활용했다. 결과가 만족스럽다."} {"input":"I analyzed the dataset using pandas and numpy. The results were quite interesting."}

아래는 코드 입니다.

    


# python -m pip install kss spacy langdetect sentence-transformers umap-learn hdbscan
# python -m spacy download en_core_web_sm

import json
import numpy as np
from langdetect import detect, DetectorFactory
from kss import split_sentences as split_ko
import spacy
from sentence_transformers import SentenceTransformer
import umap
import hdbscan

# 2	자잘한 클러스터 폭증
# 5	적당 (추천 시작점)
# 10	큰 주제만 남음
min_cluster_size = 5
min_samples = min_cluster_size // 2

# -----------------------------------
# 0. 초기 설정
# -----------------------------------

DetectorFactory.seed = 42  # langdetect 재현성
nlp_en = spacy.load("en_core_web_sm")

model = SentenceTransformer(
    "paraphrase-multilingual-mpnet-base-v2"
)

# -----------------------------------
# 1. 언어별 문장 분리 함수
# -----------------------------------

def split_english(text: str):
    doc = nlp_en(text)
    return [sent.text.strip() for sent in doc.sents if sent.text.strip()]

def split_korean(text: str):
    try:
        # mecab이 있으면 사용
        return split_ko(text, backend="mecab", strip=True)
    except ImportError:
        # 없으면 기본 backend로 fallback
        return split_ko(text, strip=True)

def split_sentences_auto(text: str):
    """
    언어 감지 후 자동 분기
    """
    try:
        lang = detect(text)
    except Exception:
        return [text]

    if lang == "ko":
        sents = split_korean(text)
    elif lang == "en":
        sents = split_english(text)
    else:
        # 기타 언어 or 짧은 텍스트
        sents = [text]

    return sents if sents else [text]

# -----------------------------------
# 2. JSONL 로드 + 문장 분리
# -----------------------------------

documents = []    # 문장 리스트
raw_texts = []    # 원문

with open("input.jsonl", "r", encoding="utf-8") as f:
    for line in f:
        line = line.strip()

        # ✅ 빈 줄 무시
        if not line:
            continue
            
        obj = json.loads(line)
        text = obj["input"].strip()

        raw_texts.append(text)
        sentences = split_sentences_auto(text)
        documents.append(sentences)

# -----------------------------------
# 3. Sentence-BERT 문장 임베딩
# -----------------------------------

doc_embeddings = []

for sentences in documents:
    sent_embeddings = model.encode(
        sentences,
        convert_to_numpy=True,
        normalize_embeddings=True
    )

    # ✅ 문단 임베딩 = 문장 평균
    doc_embedding = sent_embeddings.mean(axis=0)
    doc_embeddings.append(doc_embedding)

doc_embeddings = np.vstack(doc_embeddings)

# -----------------------------------
# 4. UMAP 차원 축소
# -----------------------------------

umap_embeddings = umap.UMAP(
    n_neighbors=15,
    n_components=5,
    metric="cosine",
    random_state=42
).fit_transform(doc_embeddings)

# -----------------------------------
# 5. HDBSCAN 클러스터링
# -----------------------------------

clusterer = hdbscan.HDBSCAN(
    min_cluster_size=min_cluster_size,
    min_samples=min_samples,
    metric="euclidean"
)

labels = clusterer.fit_predict(umap_embeddings)

# -----------------------------------
# 6. 결과 출력
# -----------------------------------

for i, label in enumerate(labels):
    print(f"[클러스터 {label}] {raw_texts[i]}")


from collections import defaultdict

# 클러스터별로 묶기
clustered = defaultdict(list)

for text, label in zip(raw_texts, labels):
    clustered[label].append(text)

# 결과 출력
for label in sorted(clustered.keys()):
    if label == -1:
        print("\n[Noise / Outlier]")
    else:
        print(f"\n[클러스터 {label}] ({len(clustered[label])}개)")

    for t in clustered[label]:
        print(f"- {t}")
        
# -----------------------------------
# 7. 결과 JSONL 저장
# -----------------------------------

with open("result.jsonl", "w", encoding="utf-8") as f:
    for i, label in enumerate(labels):
        out = {
            "input": raw_texts[i],
            "cluster_id": int(label)
        }
        f.write(json.dumps(out, ensure_ascii=False) + "\n")

    
실행결과
    
[클러스터 0] 오늘 날씨가 정말 좋다. 하늘이 맑아서 기분이 상쾌하다. 오랜만에 산책을 나갔다.
[클러스터 1] 비가 하루 종일 내렸다. 우산을 챙기지 않아서 옷이 다 젖었다. 날씨가 우울하다.
[클러스터 1] 기온이 갑자기 떨어졌다. 바람도 많이 불어서 체감 온도가 낮다.
[클러스터 0] 점심으로 김치찌개를 먹었다. 국물이 진하고 고기가 부드러웠다. 다음에는 또 오고 싶다.
[클러스터 0] 저녁에 친구들과 치킨을 시켜 먹었다. 양이 많고 바삭해서 만족스러웠다.
[클러스터 0] 이탈리안 레스토랑에 갔다. 파스타와 피자가 정말 맛있었다. 분위기도 좋았다.
[클러스터 1] 파이썬으로 머신러닝을 공부하고 있다. 데이터 전처리가 가장 어렵다. 그래도 재미있다.
[클러스터 1] 딥러닝 모델의 성능을 개선했다. 하이퍼파라미터 튜닝이 효과적이었다.
[클러스터 1] 자연어 처리를 위해 Sentence-BERT를 사용하고 있다. 임베딩 성능이 매우 좋다.
[클러스터 1] 주식 시장이 크게 하락했다. 투자 심리가 위축되고 있다. 당분간 변동성이 클 것 같다.
[클러스터 1] 비트코인 가격이 다시 상승했다. 가상자산 시장에 관심이 몰리고 있다.
[클러스터 1] 환율 변동이 심해지고 있다. 수입 기업들의 부담이 커지고 있다.
[클러스터 0] The weather is really nice today. The sky is clear and blue. I decided to take a walk.
[클러스터 1] It rained all day. I forgot my umbrella and got completely soaked.
[클러스터 1] The temperature dropped suddenly. It feels much colder than yesterday.
[클러스터 0] I had pasta for lunch. The sauce was rich and delicious. I would love to visit again.
[클러스터 0] We ordered fried chicken for dinner. It was crispy and well seasoned.
[클러스터 0] The restaurant had a great atmosphere. The food was amazing and fresh.
[클러스터 1] I am studying machine learning with Python. Data preprocessing is harder than expected.
[클러스터 1] The deep learning model achieved better accuracy. Hyperparameter tuning really helped.
[클러스터 1] Sentence embeddings are useful for text clustering. SBERT works very well.
[클러스터 1] The stock market dropped significantly today. Investors are getting nervous.
[클러스터 1] Bitcoin prices are rising again. The crypto market is becoming volatile.
[클러스터 1] Exchange rates are fluctuating rapidly. Global markets are reacting.
[클러스터 1] 오늘은 회의가 많았다. 프로젝트 일정에 대해 논의했다. 생각보다 시간이 오래 걸렸다.
[클러스터 1] 팀원들과 협업이 잘 되고 있다. 커뮤니케이션이 프로젝트 성공의 핵심이다.
[클러스터 -1] I had a meeting all morning. We discussed the project timeline in detail.
[클러스터 1] Team collaboration is going well. Clear communication makes everything easier.
[클러스터 1] 파이썬으로 데이터 분석을 진행했다. 판다스와 넘파이를 활용했다. 결과가 만족스럽다.
[클러스터 1] I analyzed the dataset using pandas and numpy. The results were quite interesting.

[Noise / Outlier]
- I had a meeting all morning. We discussed the project timeline in detail.

[클러스터 0] (8개)
- 오늘 날씨가 정말 좋다. 하늘이 맑아서 기분이 상쾌하다. 오랜만에 산책을 나갔다.
- 점심으로 김치찌개를 먹었다. 국물이 진하고 고기가 부드러웠다. 다음에는 또 오고 싶다.
- 저녁에 친구들과 치킨을 시켜 먹었다. 양이 많고 바삭해서 만족스러웠다.
- 이탈리안 레스토랑에 갔다. 파스타와 피자가 정말 맛있었다. 분위기도 좋았다.
- The weather is really nice today. The sky is clear and blue. I decided to take a walk.
- I had pasta for lunch. The sauce was rich and delicious. I would love to visit again.
- We ordered fried chicken for dinner. It was crispy and well seasoned.
- The restaurant had a great atmosphere. The food was amazing and fresh.

[클러스터 1] (21개)
- 비가 하루 종일 내렸다. 우산을 챙기지 않아서 옷이 다 젖었다. 날씨가 우울하다.
- 기온이 갑자기 떨어졌다. 바람도 많이 불어서 체감 온도가 낮다.
- 파이썬으로 머신러닝을 공부하고 있다. 데이터 전처리가 가장 어렵다. 그래도 재미있다.
- 딥러닝 모델의 성능을 개선했다. 하이퍼파라미터 튜닝이 효과적이었다.
- 자연어 처리를 위해 Sentence-BERT를 사용하고 있다. 임베딩 성능이 매우 좋다.
- 주식 시장이 크게 하락했다. 투자 심리가 위축되고 있다. 당분간 변동성이 클 것 같다.
- 비트코인 가격이 다시 상승했다. 가상자산 시장에 관심이 몰리고 있다.
- 환율 변동이 심해지고 있다. 수입 기업들의 부담이 커지고 있다.
- It rained all day. I forgot my umbrella and got completely soaked.
- The temperature dropped suddenly. It feels much colder than yesterday.
- I am studying machine learning with Python. Data preprocessing is harder than expected.
- The deep learning model achieved better accuracy. Hyperparameter tuning really helped.
- Sentence embeddings are useful for text clustering. SBERT works very well.
- The stock market dropped significantly today. Investors are getting nervous.
- Bitcoin prices are rising again. The crypto market is becoming volatile.
- Exchange rates are fluctuating rapidly. Global markets are reacting.
- 오늘은 회의가 많았다. 프로젝트 일정에 대해 논의했다. 생각보다 시간이 오래 걸렸다.
- 팀원들과 협업이 잘 되고 있다. 커뮤니케이션이 프로젝트 성공의 핵심이다.
- Team collaboration is going well. Clear communication makes everything easier.
- 파이썬으로 데이터 분석을 진행했다. 판다스와 넘파이를 활용했다. 결과가 만족스럽다.
- I analyzed the dataset using pandas and numpy. The results were quite interesting.