Loading the catalog…
Loading the catalog…
회고 기간: 26년 9월 28일 ~ 10월 2일 시작하며 지금까지는 LangChain·LangGraph 위에서 에이전트와 RAG를 만드는 "프레임워크 레벨"의 학습이 이어졌다면, 이번 주는 한 단계 더 아래와 위로 동시에 내려가고 올라간 한 주였다. MCP(Model Context Protocol)로 "모델이 외부 도구·서버와 어떻게 표준화된 방식으로 통신하는가"를 배웠고, HuggingFace 생태계 실습에서는 반대로 "모델 내부에서 웨이트가 실제로 어떻게 forward 연산으로 이어지는가"를 바닥까지 내려가서 확인했다. Liked MCP 실습에서 client.py 가 session.list_tools() 로 받아온 MCP 서버의 도구 목록을, OpenAI 스타일의 {"type": "function", "function": {...}} 스키마로 변환해 llm.bind_tools() 에 그대로 넘기는 구조가 인상 깊었다. MCP 서버가 어떤 Tool을 갖고 있는지 클라이언트가 미리 알 필요 없이, 런타임에 서버와 대화하며 도구 목록을 동적으로 받아온다 는 점이, 지금까지 코드에 직접 @tool 함수를 나열해온 방식과 가장 크게 다른 부분이었다. tools_response = await session.list_tools() self.available_tools = [ { "type": "function", "function": { "name": tool.name, "description": tool.description, "parameters": tool.input_schema, }, } for tool in tools_response.tools ] self.llm_with_tools = self.llm.bind_tools(self.available_tools) server.py 에 등록된 도구 중 search_financial_guide 가, 예전에 RAG 실습에서 만들었던 "금융투자협회 투자길라잡이" FAISS VectorDB를 그대로 재사용하고 있다는 걸 발견한 게 반가웠다. 그동안 따로따로 배운 RAG와 MCP가, 실제로는 "RAG로 만든 검색 기능을 MCP Tool 하나로 노출해 다른 에이전트가 가져다 쓸 수 있게 한다"는 식으로 자연스럽게 이어진다는 걸 코드로 확인할 수 있었다. HuggingFace 실습 마지막 "from_pretrained 딥다이브"에서, safetensors 로 직접 읽은 텐서 딕셔너리만으로 GPT-2의 forward 연산(임베딩 → 12개 Attention/MLP 블록 → LayerNorm → weight tying)을 손으로 구현하고, 그 결과가 실제 HuggingFace 모델의 출력과 소수점 5자리( 8.39e-05 )까지 일치하는 걸 확인한 게 이번 주, 아니 지금까지의 실습 중에서도 손꼽히게 짜릿한 순간이었다. 심지어 이 수동 forward만으로 "Hello, my name is"에 이어 "John. I'm a writer, and"까지 자기회귀 생성에 성공했다. print("직접 구현 vs HF forward 최대 오차:", max_diff) # 8.39e-05 print("✅ 사실상 동일한가? (atol=1e-3)", torch.allclose(logits_scratch, logits_hf, atol=1e-3)) # True Lacked HuggingFace 실습 초반에 "GPU: NVIDIA RTX 4090 (8GB VRAM)"라는 실습 환경 안내가 있었는데, 실제로 노트북을 실행한 로컬 환경에서는 ⚠️ CUDA GPU를 찾을 수 없습니다 가 떴다. 결국 FP16 모델로 "파이썬의 장점 3가지" 하나를 생성하는 데 1671초(약 28분)가 걸렸고, 처리 속도도 초당 0.1 토큰에 그쳤다. 처음엔 코드가 멈춘 줄 알고 당황했는데, 알고 보니 CPU로 1.5B 모델을 돌리고 있었던 것이었다. RunPod 같은 클라우드 GPU 환경이 왜 필요한지, 이 느린 로컬 실행을 직접 겪고 나서야 체감했다. 더 헷갈렸던 건, 같은 CPU 환경인데도 4bit 양자화 모델이 FP16 모델보다 오히려 훨씬 빨랐다 는 점이다. FP16은 초당 0.1토큰, 4bit는 초당 3.6토큰으로 36배 가까이 차이가 났다. 처음엔 "양자화는 메모리만 아끼고 속도는 비슷하거나 더 느릴 것"이라고 생각했는데, CPU에서는 가중치 자체의 크기가 작아지면 메모리에서 읽어오는 양이 줄어들어 오히려 속도에 더 유리할 수 있다는 걸, 직접 두 숫자를 비교하고서야 알게 됐다. FP16 : ⏱️ 소요 시간: 1671.24초 | ⚡ 처리 속도: 0.1 tokens/sec 4bit : ⏱️ 소요 시간: 35.42초 | ⚡ 처리 속도: 3.6 tokens/sec Learned MCP (Model Context Protocol) 클라이언트-서버 구조 client.py 는 stdio_client 로 MCP 서버 프로세스를 띄우고 ClientSession 을 생성해 session.initialize() 로 연결을 초기화한 뒤, session.list_tools() 로 받은 도구 목록을 LangChain의 bind_tools() 형식으로 변환했다. LLM이 tool_calls 를 반환하면 session.call_tool(name, arguments) 로 실제 MCP 서버의 도구를 호출하고, 그 결과를 ToolMessage 로 감싸 다시 LLM에 전달해 최종 답변을 받는 흐름은, 지난주 배운 로컬 @tool Function Calling과 거의 동일한 패턴이었다. 다른 점은 도구가 "내 파이썬 코드 안"이 아니라 "별도 프로세스로 뜬 MCP 서버 안"에 있고, 그 목록을 런타임에 동적으로 받아온다는 것이었다. server.py 는 @mcp.tool() 로 계산기(AST 샌드박스 기반 safe_calculate ), 날씨 조회(Open-Meteo API), 웹 검색(Tavily), 구글 캘린더 일정 조회, 그리고 금융 문서 VectorDB 검색( search_financial_guide )까지 5개의 외부 어댑터를 도구로 등록했다. @mcp.resource() 로는 시스템 정보( system://info )와 앱 사용 가이드( config://app-guide ) 같은, Tool과는 성격이 다른 "읽기 전용 정보"도 함께 노출할 수 있다는 걸 확인했다. 각 Tool은 외부 서비스 연동 로직( WeatherAdapter , TavilySearchEngine , GoogleCalendarAdapter , VectorDBAdapter )을 별도 어댑터 클래스로 분리해두고, Tool 함수 자체는 그 어댑터를 호출해 결과를 포맷팅하는 얇은 래퍼 역할만 한다는 구조적 특징도 눈에 띄었다. HuggingFace 생태계와 파인튜닝 이전 단계 - 모델 내부 들여다보기 AutoModelForCausalLM / AutoTokenizer 로 Qwen2.5-1.5B-Instruct를 로딩해 FP16 수동 생성과 pipeline API 추론을 비교했고, BitsAndBytesConfig 로 NF4 4bit 양자화(QLoRA 논문에서 제안된 기법, 이중 양자화로 추가 메모리 절약)를 적용해 FP16 대비 메모리 절약 효과를 확인했다. 가장 핵심적인 배움은 "심화" 섹션이었다. hf_hub_download 로 config.json (모델 설계도)과 model.safetensors (가중치 파일)를 직접 받아, safetensors.torch.load_file 로 {이름: 텐서} 딕셔너리를 열어봤다. AutoModelForCausalLM.from_config() 로 랜덤 웨이트짜리 모델 뼈대를 만든 뒤, load_state_dict() 가 이름 문자열 매칭 만으로 체크포인트 텐서를 모델에 할당한다는 걸 직접 재현했다. 마지막으로 이 모든 텐서를 nn.Module 없이 순수 행렬곱(Attention, MLP, LayerNorm, weight tying)으로만 이어붙인 수동 forward 함수를 작성해, 실제 HuggingFace 모델과 동일한 출력을 얻어냈다. from_pretrained() 한 줄이 사실은 "다운로드 → 스켈레톤 생성 → state_dict 로드 → 이름 매칭 할당"이라는 네 단계의 자동화일 뿐이라는 게, 이 실습 전체의 결론이었다. 참고로 이번에 다룬 노트북은 LoRA·Trainer 기반의 실제 파인튜닝 학습 코드까지는 포함하지 않았고, "LoRA 어댑터 파일이 왜 작은가?"(전체가 아닌 일부 이름의 저랭크 텐서만 저장되기 때문)처럼 다음 단계인 파인튜닝을 이해하기 위한 밑그림(모델 구조와 웨이트 로딩 메커니즘)을 다지는 내용이었다. 이번 주는 MCP로 "도구가 표준화된 프로토콜을 통해 모델과 분리된 채로 연결된다"는 확장성의 측면과, HuggingFace 딥다이브로 "그 모델이라는 것도 결국 이름 붙은 텐서 뭉치와 그 텐서들의 정해진 행렬곱일 뿐"이라는 환원주의적인 이해를, 같은 한 주 안에서 양쪽으로 경험한 게 특히 기억에 남는다. 특히 직접 구현한 forward가 HuggingFace의 공식 구현과 소수점 단위까지 일치하는 걸 확인한 순간 은, 그동안 블랙박스로만 여겼던 from_pretrained() 라는 한 줄이 실은 전혀 신비로운 게 아니라는 걸 몸으로 확인시켜준 경험이었다.
What RADAR observed and classified to build this opportunity. It is what the source published, not a verification that the offer is still active.
[SK네트웍스 Family AI 캠프] 35기 13주차 회고. 회고 기간: 26년 9월 28일 ~ 10월 2일 시작하며 지금까지는 LangChain·LangGraph 위에서 에이전트와 RAG를 만드는 "프레임워크 레벨"의 학습이 이어졌다면, 이번 주는 한 단계 더 아래와 위로 동시에 내려가고 올라간 한 주였다. MCP(Model Context Protocol)로 "모델이 외부 도구·서버와 어떻게 표준화된 방식으로 통신하는가"를 배웠고, HuggingFace 생태계 실습에서는 반대로 "모델 내부에서 웨이트가 실제로 어떻게 forward 연산으로 이어지는가"를 바닥까지 내려가서 확인했다. Liked MCP 실습에서 client.py 가 session.list_tools() 로 받아온 MCP 서버의 도구…
Open source