여기에서 해보고 싶은 것은 "동탄" 키워드가 들어간 최근 블로그를 검색해서

그 제목과 본문 내용, 링크 값을 얻어오는 코드를 작성해보고자 한다.

 

0. 개발 환경

- OS: Ubuntu 20.04

- Lang: Python 3.10.9

 

 

1. 준비

① NAVER API를 사용하기 위해 API 키를 생성하자.

    - NAVER 서비스 API 사용 준비

 

② 환경변수를 다루기 위해서 dotenvx를 사용해보자.

    - 아는 사람만 쓴다는 Config 관리자 - dotenv, dotenvx

 

 

2. 코드 작성

일단 API 호출을 위해 requests 패키지를 사용하기로 했다.

 

[ requirements.txt ]

requests==2.32.3

 

가급적 클래스 구조로 작성해봤다.

[ main.py ]

import requests
import os

class BlogPost:
    def __init__(self, title, description, link):
        self.title = title.replace("<b>", "").replace("</b>", "")
        self.description = description.replace("<b>", "").replace("</b>", "")
        self.link = link

    def __str__(self):
        return f"Title: {self.title}\nDescription: {self.description}\nURL: {self.link}\n"

class NaverBlogSearcher:
    def __init__(self):
        self.client_id = os.getenv("NAVER_CLIENT_ID")  # 환경변수에서 Client ID 읽어오기
        self.client_secret = os.getenv("NAVER_CLIENT_SECRET")  # 환경변수에서 Client Secret 읽어오기

        # 환경변수 값이 없을 때 예외 처리
        if not self.client_id or not self.client_secret:
            raise ValueError("NAVER_CLIENT_ID and NAVER_CLIENT_SECRET must be set as environment variables.")

    def get_blog_posts(self, query, display=10):
        # 요청 URL 및 헤더 구성
        url = f"https://openapi.naver.com/v1/search/blog.json?query={query}&display={display}&sort=date"
        headers = {
            "X-Naver-Client-Id": self.client_id,
            "X-Naver-Client-Secret": self.client_secret,
        }

        # 네이버 API에 요청 보내기
        response = requests.get(url, headers=headers)
        
        if response.status_code == 200:
            return self.parse_response(response.json())
        else:
            print(f"Error: {response.status_code}, {response.text}")
            return []

    def parse_response(self, data):
        # 응답 데이터 파싱
        blogs = data.get("items", [])
        blog_posts = [BlogPost(blog.get("title"), blog.get("description"), blog.get("link")) for blog in blogs]
        return blog_posts

if __name__ == "__main__":
    # "동탄" 검색어로 최신 블로그 정보 가져오기
    try:
        searcher = NaverBlogSearcher()
        blog_posts = searcher.get_blog_posts("동탄", 3)
        for post in blog_posts:
            print(post)
    except ValueError as e:
        print(e)

 

환경 변수도 작성했다.

[ .env ]

NAVER_CLIENT_ID=""
NAVER_CLIENT_SECRET=""

 

 

3. 실행

dotenvx를 사용해서 실행했다.

> dotenvx run -f .env -- python main.py

 

나름 잘 진행되었다 !!! (스스로 뿌듯~)

반응형

옛날에 한 번 포스팅을 했었는데, 업데이트가 필요해서 다시 작성해본다.

- https://www.whatwant.com/entry/Naver-API-사용-준비하기

 

1. NAVER Developers

네이버 개발자 사이트에 방문해서 로그인까지 진행하자.

- https://developers.naver.com/

 

NAVER Developers

 

 

2. 서비스 API

일단 여기에서는 "검색"을 위한 API 사용 신청하는 과정을 기준으로 설명해보겠다.

 

서비스 API

 

상단 메뉴에서 "서비스 API - 검색" 메뉴를 선택해보자.

 

검색

 

3. 오픈 API 이용 신청

처음 사용자는 이용약관 동의나 계정 설정 등을 요구할 수도 있다.

나는 예전에 신청했던 이력이 있어서인지 바로 애플리케이션 등록 창으로 이동되었다.

 

애플리케이션 등록

 

"애플리케이션 이름" 적절하게 창작하면 되고,

"사용 API"는 검색을 선택했다. 각자 필요한 것 추가해도 된다.

 

"비로그인 오픈 API 서비스 환경"은 사용할 상황에 따라 잡아주면 되는데,

나는 일단 "WEB 설정"으로 하고 적당한 도메인 정보를 넣어주었다.

 

4. 애플리케이션 정보

사용할 때 필요한 "Client ID"와 "Client Secret"이 발행되었다.

 

애플리케이션 정보

 

하루에 2만5천번 호출할 수 있네!!!!

 

반응형

PDF, DOCX, PPTX 같은 문서 파일이나 이미지, HTML 등을

여러 용도로 사용하기 좋게 Markdown, Json 형식으로 변환해주는 도구를 찾았다.

 

사실 너무 유명해서 알만한 사람들은 이미 다 알고 있는 것 같지만 ^^

- https://ds4sd.github.io/docling/

 

Docling

 

MIT 라이선스인 오픈소스 프로젝트이다.

- https://github.com/DS4SD/docling

 

GitHub

 

파이썬 패키지이기 때문에 파이썬 개발 환경이 필요하다 ^^

 

다양한 버전의 파이썬 활용을 위한 pyenv 환경이 필요하다면 아래 포스팅을 참고하기 바란다.

- https://www.whatwant.com/entry/pyenv

 

1. Installation

가상환경 생성 후 docling 설치까지 진행해보자.

cuda, torch 및 의존성 있는 패키지들이 엄청 많이 설치되고 용량도 커서 시간도 좀 걸린다.

 

> python -m venv .venv

> source .venv/bin/activate

> pip install docling

 

2. Usage

공식적으로 알려주는 샘플 코드를 작성 후 실행해보자.

- https://ds4sd.github.io/docling/usage/

 

from docling.document_converter import DocumentConverter

source = "https://arxiv.org/pdf/2408.09869"  # PDF path or URL
converter = DocumentConverter()
result = converter.convert(source)
print(result.document.export_to_markdown())  # output: "### Docling Technical Report[...]"

 

우쒸... GPU 환경이 필수인가보다.

그런데, Colab 환경에서도 정상적인 결과가 나오진 않는다.

 

 

 

3분 정도가 소요되어 정상 완료한 것처럼 나오지만,

출력되는 내용이 없다.

 

잘못된 것인줄 알았는데, 출력 결과 전체 화면 보기를 하니 제대로 보였다.

 

 

엔터(줄바꿈) 없이 너무 길게 string이 나와서 출력 결과가 안보였던 것이다.

뭐 일단, Colab으로 테스트를 해볼 수는 있었다.

 

음... 재미있긴 하지만,

속도가 그다지 빠르지 않아서... (A100이나 H100 환경에서는 조금 빠르려나!? 함 해볼까...!?)

자주 사용할 아이는 아닐 것 같다.

반응형

리눅스를 좋아하는, 특히 커맨드-라인 인터페이스를 좋아하는 분들은

각자 나름의 커스터마이징된 환경 꾸미는 것을 좋아하는 경우가 많다.

 

우분투와 같은 리눅스를 설치하면 기본적으로 bash가 설치되지만

리눅스를 많이 사용하는 분들은 zsh으로 바꿔서 사용하는 것 처럼 ... ^^

 

이처럼 커맨드-라인을 사용하는 환경을 커스터마이징 할 때

자주 언급되는 유틸리티 중 하나가 바로 "fzf (command-line fuzzy finder)" 이다.

- https://junegunn.github.io/fzf/

 

fzf

 

버전이 아직도 v0.56.3 에 머물러 있음에도 (ㅋㅋㅋ 절대 v1.0 릴리즈를 하지 않겠다는 의지?!)

Star 갯수에서 유추할 수 있듯이 global에서 유명한 툴이다.

 

GitHub

 

우리나라에서 더더욱 유명한 이유는 !!!

개발자가 우리나라 분이시다 !!!

 

Junegunn Choi

 

푸릇푸릇한 잔디밭도 대단하고,

Sponsors 목록.... 오!!!!! 국내 개발자 중에 저 정도의 Sponsors 목록을 갖고 있는 분은 처음 봤다!!!

 

 

1. Installation

Homebrew를 이용해서 설치하는 것이 기본적으로 권장하는 방법이고,

운영 체제에 따라서 편하게 설치할 수 있는 다양한 방법을 제공해주고 있지만

(개인적인 취향으로) 지원만 해준다고 하면 git clone 방식으로 설치하는 것을 권장한다.

- https://github.com/junegunn/fzf?tab=readme-ov-file#using-git

 

git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install

 

버전 업그레이드가 필요하다고 하면 다음과 같이 할 수 있다.

- https://github.com/junegunn/fzf?tab=readme-ov-file#upgrading-fzf

 

cd ~/.fzf && git pull && ./install

 

 

2. shell integration (zsh)

설치 과정에서 자동으로 셋업 해주기는 하는데,

혹시 잘 안되는 경우가 있을까 하여 추가적으로 확인하는 과정을 넣어보았다.

 

가이드 문서에는 다음과 같이 되어있다. (zsh이 아닌 경우 아래 링크 참조)

- https://github.com/junegunn/fzf?tab=readme-ov-file#setting-up-shell-integration

 

# Set up fzf key bindings and fuzzy completion
source <(fzf --zsh)

 

하지만, 설치 과정에서 자동으로 반영해준 내역은 조금 다르다.

 

.zshrc

 

어!? 뭔가 파일을 불러오네!?

그러면, 그 파일을 추가로 확인해보자.

 

.fzf.zsh

 

가이드 문서에 있는 내용과 결국은 같기는 한데, 경로 추가도 포함되어 있어서 더 좋은 것 같다.

 

뭐, 여하튼 이렇게 잘 반영되어 있으면 좋고,

혹시 반영이 안되어 있으신 분은 위 내용 참고해서 반영해주면 된다.

 

그런 후에, 터미널을 재시작 하던지 아니면 "source ~/.zshrc" 하던지 하고

fzf가 잘 설치되어 있는지 확인해보면 된다.

 

version

 

3. Simple Usage

nano 에디터를 이용해서 어떤 파일을 편집하고 싶다고 해보자.

그런데, 파일 이름은 알고 있지만 어느 경로에 있는지 까지는 모른다거나 타이핑하기 귀찮은 상황이라면...

 

> nano $(fzf)

 

제일 아래 부분에서 원하는 파일 이름을 하나씩 타이핑하면

위에 추천하는 파일들을 실시간으로 업데이트 하면서 보여준다.

 

원하는 파일이 있으면 화살표 키를 이용해서 고른 다음에 엔터를 치면 된다.

 

4. Short-Key

단축키도 지원을 해준다.

커맨드-라인 상태에서 "Ctrl + R" 키를 누르면 이전에 사용했던 이력을 보여준다.

 

 

현재 디렉토리 기준으로 하위 디렉토리를 포함한 파일들의 목록을 보여주는 것은 "Ctrl + T"이다.

 

 

이외에도 다양한 기능들을 제공해주고 있는데...

한 번에 다 공부하기에는 부담스러워서 이번에는 일단 여기까지~~~

 

더 알고 싶으신 분들은 공식 문서를 참고하기 바란다.

- https://github.com/junegunn/fzf?tab=readme-ov-file#usage

 

반응형

그동안 블로그 포스팅을 하면서

티스토리에서 코드 출력을 위해 기능을 제공해주고 있다는 것을 지금까지 몰랐다.

 

이런 바보!

 

이렇게 예쁘게 출력을 해준다.

from transformers import pipeline, AutoTokenizer, AutoModelForSequenceClassification

tokenizer = AutoTokenizer.from_pretrained("maywell/Synatra-42dot-1.3B")
model = AutoModelForSequenceClassification.from_pretrained("maywell/Synatra-42dot-1.3B")

classifier_ko = pipeline("sentiment-analysis", model=model, tokenizer=tokenizer)

classifier_ko("정말 니가 싫어")

 

그런데,

깔끔하긴 한데... 뭔가 좀 아쉽다.

이게 훨씬 더 예쁜 것 같다!!!! 

 

 

소스 코드를 이렇게 예쁜 이미지로 만들어 주는 사이트를 소개해보고자 한다 ^^

- https://ray.so/

 

사이트에 방문해서 소스 코드를 붙여 넣기 하고,

하단의 옵션을 적절하게 만져주면 된다.

 

예쁘게 만들었다면,

오른쪽 상단의 Export Image를 통해 그림파일로 내려 받으면 된다.

 

 

해당 사이트는 사실 더 많은 기능을 제공해 준다.

 

정말 가볍고, 깔끔하고, 유용한 기능을 많이 제공해주는 아름다운 사이트이다.

 

[추가] 로컬에서 띄울 수도 있다.

- https://github.com/raycast/ray-so

반응형

GitHub에서 여러 LLM 모델들을 가지고 놀 수 있는 서비스를 제공하고자 하고 있어서

이것을 소개해보려 한다.

 

아직은 정식 서비스를 하고 있지 않아서인지, 메뉴가 꼭 꼭 숨어있다.

 

아! 아직은 Preview 상태라서 해당 메뉴가 보이지 않는 분들이 계실 수도 있다.

그런 분들은 그냥 이런게 곧 나오겠구나~하고 구경 먼저 해보시길 ^^

 

일단 로그인을 하고...

GitHub

 

왼쪽 위 메뉴 버튼을 눌러 펼친 다음에

"Marketplace"를 선택하자.

Menu

 

Marketplace 메뉴들을 보면 "Models"를 발견할 수 있다.

Models

 

여러 LLM 모델들을 볼 수 있는데,

일단 친근한 GPT-4o를 선택해보자.

OpenAI GPT-4o

 

오른쪽 위의 "Playground" 버튼을 선택해보자.

Playground

 

System prompt를 비롯해서 Max Tokens라던지, Temperature 등 여러 parameter들을 설정할 수도 있다.

직접 프롬프트를 입력하면 대기시간 없이 즉시 응답을 해준다.

prompt

 

한글 출력이 깨지는 것이 있는데, model의 잘못인지 GitHub에서의 출력 문제인지는 불분명하다.

 

말만 들어봤던 Mistral 모델을 가지고도 한 번 해봤다.

한글도 잘 알아듣고, 결과도 나름 괜찮네!?

Mistral

 

현재 GitHub Models에서 사용해볼 수 있는 model들은 다음과 같다.

 

이걸 가지고 뭔가 재미난 것들을 해볼 수도 있을 것 같은데...

Preview 기간이 끝나면 당연하게도 유료 서비스가 될 것 같아서 ^^

반응형

오늘은 왠지 LLAMA가 눈길을 끌어서 ...

 

llama-3.2-Korean-Bllossom-3B

 

친절하게 예제 코드도 제시해주고 있다.

 

import torch
from transformers import AutoTokenizer, AutoModelForCausalLM

model_id = 'Bllossom/llama-3.2-Korean-Bllossom-3B'

tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
    model_id,
    torch_dtype=torch.bfloat16,
    device_map="auto",
)
instruction = "철수가 20개의 연필을 가지고 있었는데 영희가 절반을 가져가고 민수가 남은 5개를 가져갔으면 철수에게 남은 연필의 갯수는 몇개인가요?"

messages = [
    {"role": "user", "content": f"{instruction}"}
    ]

input_ids = tokenizer.apply_chat_template(
    messages,
    add_generation_prompt=True,
    return_tensors="pt"
).to(model.device)

terminators = [
    tokenizer.convert_tokens_to_ids("<|end_of_text|>"),
    tokenizer.convert_tokens_to_ids("<|eot_id|>")
]

outputs = model.generate(
    input_ids,
    max_new_tokens=1024,
    eos_token_id=terminators,
    do_sample=True,
    temperature=0.6,
    top_p=0.9
)

print(tokenizer.decode(outputs[0][input_ids.shape[-1]:], skip_special_tokens=True))

 

3B 모델에서 과연 저 문제를 풀 수 있을까?

 

구글 코랩에서 위 코드를 실행해보자. (나는 GPU도 없는 가난한 머글이니까 ㅠㅠ)

Exception

 

어?! 시키는 그대로 했는데, 왜?!

 

구글 코랩에서 기본 버전을 업그레이드 해주면 발생하지 않을테지만,

현재는 transformers, tokenizers 버전이 낮아서 발생하는 것으로 보인다.

 

!pip install --upgrade transformers tokenizers

pip install

 

설치가 끝나면 세션 재시작을 요구한다.

하면 된다.

 

그리고 나서 실행하면 시간이 좀 걸리지만... 잘 된다.

철수가 20개의 연필을 가지고 있었고 영희가 절반을 가져가면, 영희가 가져간 연필은 20 / 2 = 10개입니다.

철수가 남은 연필은 20 - 10 = 10개입니다. 민수가 5개를 가져가면, 철수가 남은 연필은 10 - 5 = 5개가 됩니다.

따라서 철수가 남은 연필의 갯수는 5개입니다.

 

그리고, 문제도 잘 푼다!!!

 

반응형

이왕 살펴보는 김에 하나 더 해보려고 한다.

Zero-shot classification

 

원하는 결과가 나오지 않을까봐 살짝 무섭기도 한데.... ^^

 

뉴스 제목을 보고 어떤 카테고리인지 맞춰보는 것을 한 번 해보려고 한다.

 

 

네이버 뉴스 데이터를 이용해보자.

naver

 

정치, 경제, 사회 등의 카테고리 별로 현재 상단에 있는 뉴스 제목들을 가지고 와봤다.

from transformers import pipeline

classifier = pipeline("zero-shot-classification")

labels = ["정치", "경제", "사회", "생활/문화", "IT/과학", "세계"]

articles = [
    "尹 대통령 선물받은 투르크 국견 해피·조이, 관저 떠나 서울대공원으로",
    "트럼프, 인플레 우려에 관세폭탄 못할것",
    "똑바로 살겠다…반성문 3번 쓴 음주뺑소니 김호중, 검찰은 징역 3년6개월",
    "천재화가 천경자 특별전 개막..미공개 작품도 선 보여",
    "매출 25% AI투자, 초개인화 'AI 검색' 일상속으로",
    "네타냐후, 트럼프 당선에 ‘폭주’…팔·레바논 등 공격 100명 사망"
]

classifier(articles, candidate_labels=labels)

 

실행결과는 다음과 같이 나온다.

 

정답률이 엄청 안좋기 때문에 ^^

Top3 포함되면 정답으로 계산해서 33점.

 

 

이번에는 ko-LLM 리더보드에서 현재 1위를 하고 있는 모델을 이용해봤다.

from transformers import pipeline, AutoTokenizer, AutoModelForSequenceClassification

model_name = "maywell/Synatra-42dot-1.3B"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(model_name)

classifier = pipeline("zero-shot-classification", model=model, tokenizer=tokenizer)

labels = ["정치", "경제", "사회", "생활/문화", "IT/과학", "세계"]

articles = [
    "尹 대통령 선물받은 투르크 국견 해피·조이, 관저 떠나 서울대공원으로",
    "트럼프, 인플레 우려에 관세폭탄 못할것",
    "똑바로 살겠다…반성문 3번 쓴 음주뺑소니 김호중, 검찰은 징역 3년6개월",
    "천재화가 천경자 특별전 개막..미공개 작품도 선 보여",
    "매출 25% AI투자, 초개인화 'AI 검색' 일상속으로",
    "네타냐후, 트럼프 당선에 ‘폭주’…팔·레바논 등 공격 100명 사망"
]

classifier(articles, candidate_labels=labels)

 

실행결과는 다음과 같다.

 

마찬가지로 Top3에 포함된 것 기준으로 67점이다.

 

 

혹시나 하고 ChatGPT를 시켜봤더니 Top1으로 해서 1개 빼고 모두 잘 분류했다. 역시 ChatGPT !!!

위의 작은 모델들은 Top1으로 하면 처참한 결과인데...

ChatGPT

 

뭐 결과는 조금 마음에 들지는 않지만,

그래도 머리속에 있는 아이템을 가지고 HuggingFace를 이용해서 어떻게 해야할지에 대해서는

간단히 잘 살펴본 것 같다. (ChatGPT의 위대함을 느낀 것이 더 큰가?)

반응형

+ Recent posts