diff --git "a/content/10 Wiki/11 Java/11.1 \352\270\260\354\264\210.md" "b/content/10 Wiki/11 Java/11.1 \352\270\260\354\264\210.md" index b1ce090..e2f2c12 100644 --- "a/content/10 Wiki/11 Java/11.1 \352\270\260\354\264\210.md" +++ "b/content/10 Wiki/11 Java/11.1 \352\270\260\354\264\210.md" @@ -173,7 +173,7 @@ public static double parseDouble(String s) throws NumberFormatException 다음 표에서 위에 있는 연산자부터 실행된다. -![Operater Prescedence](../../00%20Meta/02%20Images/operator-precedence.png) +![Operater Prescedence](operator-precedence.png) #### *References* diff --git a/content/00 Meta/02 Images/operator-precedence.png b/content/10 Wiki/11 Java/operator-precedence.png similarity index 100% rename from content/00 Meta/02 Images/operator-precedence.png rename to content/10 Wiki/11 Java/operator-precedence.png diff --git "a/content/10 Wiki/12 DSA/12.2 \353\254\270\354\240\234/\353\213\244\353\246\254\353\245\274 \354\247\200\353\202\230\353\212\224 \355\212\270\353\237\255.md" "b/content/10 Wiki/12 DSA/12.2 \353\254\270\354\240\234/\353\213\244\353\246\254\353\245\274 \354\247\200\353\202\230\353\212\224 \355\212\270\353\237\255/index.md" similarity index 97% rename from "content/10 Wiki/12 DSA/12.2 \353\254\270\354\240\234/\353\213\244\353\246\254\353\245\274 \354\247\200\353\202\230\353\212\224 \355\212\270\353\237\255.md" rename to "content/10 Wiki/12 DSA/12.2 \353\254\270\354\240\234/\353\213\244\353\246\254\353\245\274 \354\247\200\353\202\230\353\212\224 \355\212\270\353\237\255/index.md" index 0703e7b..2466e26 100644 --- "a/content/10 Wiki/12 DSA/12.2 \353\254\270\354\240\234/\353\213\244\353\246\254\353\245\274 \354\247\200\353\202\230\353\212\224 \355\212\270\353\237\255.md" +++ "b/content/10 Wiki/12 DSA/12.2 \353\254\270\354\240\234/\353\213\244\353\246\254\353\245\274 \354\247\200\353\202\230\353\212\224 \355\212\270\353\237\255/index.md" @@ -39,7 +39,7 @@ class Solution { } ``` -![풀이 1](../../../00%20Meta/02%20Images/trucks1.png) +![풀이 1](trucks1.png) - 시간 복잡도: $O(\verb|bridge_length|\times\verb|truck_weights.length|)$ 최악의 경우 트럭이 무거워서 다리를 1대씩 건너가면 다리 길이와 트럭 대수를 곱한 만큼 루프를 돈다. @@ -84,7 +84,7 @@ class Solution { } ``` -![풀이 2](../../../00%20Meta/02%20Images/trucks2.png) +![풀이 2](trucks2.png) - 시간 복잡도: $O(\verb|truck_weights.length|)$ 2개의 인덱스가 1씩 증가한다고 해도 트럭 개수의 2배만큼만 루프를 돌면 된다. @@ -135,7 +135,7 @@ class Solution { } ``` -![풀이 3](../../../00%20Meta/02%20Images/trucks3.png) +![풀이 3](trucks3.png) - 시간 복잡도: $O(\verb|truck_weights.length|)$ - 공간 복잡도: $O(\verb|bridge_length|)$ diff --git a/content/00 Meta/02 Images/trucks1.png "b/content/10 Wiki/12 DSA/12.2 \353\254\270\354\240\234/\353\213\244\353\246\254\353\245\274 \354\247\200\353\202\230\353\212\224 \355\212\270\353\237\255/trucks1.png" similarity index 100% rename from content/00 Meta/02 Images/trucks1.png rename to "content/10 Wiki/12 DSA/12.2 \353\254\270\354\240\234/\353\213\244\353\246\254\353\245\274 \354\247\200\353\202\230\353\212\224 \355\212\270\353\237\255/trucks1.png" diff --git a/content/00 Meta/02 Images/trucks2.png "b/content/10 Wiki/12 DSA/12.2 \353\254\270\354\240\234/\353\213\244\353\246\254\353\245\274 \354\247\200\353\202\230\353\212\224 \355\212\270\353\237\255/trucks2.png" similarity index 100% rename from content/00 Meta/02 Images/trucks2.png rename to "content/10 Wiki/12 DSA/12.2 \353\254\270\354\240\234/\353\213\244\353\246\254\353\245\274 \354\247\200\353\202\230\353\212\224 \355\212\270\353\237\255/trucks2.png" diff --git a/content/00 Meta/02 Images/trucks3.png "b/content/10 Wiki/12 DSA/12.2 \353\254\270\354\240\234/\353\213\244\353\246\254\353\245\274 \354\247\200\353\202\230\353\212\224 \355\212\270\353\237\255/trucks3.png" similarity index 100% rename from content/00 Meta/02 Images/trucks3.png rename to "content/10 Wiki/12 DSA/12.2 \353\254\270\354\240\234/\353\213\244\353\246\254\353\245\274 \354\247\200\353\202\230\353\212\224 \355\212\270\353\237\255/trucks3.png" diff --git a/content/00 Meta/02 Images/container-magic.png b/content/10 Wiki/13 Spring/13.02 DI/container-magic.png similarity index 100% rename from content/00 Meta/02 Images/container-magic.png rename to content/10 Wiki/13 Spring/13.02 DI/container-magic.png diff --git a/content/10 Wiki/13 Spring/13.02 DI.md b/content/10 Wiki/13 Spring/13.02 DI/index.md similarity index 94% rename from content/10 Wiki/13 Spring/13.02 DI.md rename to content/10 Wiki/13 Spring/13.02 DI/index.md index 0b1c19b..9352ae8 100644 --- a/content/10 Wiki/13 Spring/13.02 DI.md +++ b/content/10 Wiki/13 Spring/13.02 DI/index.md @@ -7,7 +7,7 @@ tags: ## Spring IoC Container -![Spring IoC Container](../../00%20Meta/02%20Images/container-magic.png) +![Spring IoC Container](container-magic.png) ```java // create and configure beans @@ -43,7 +43,7 @@ List userList = service.getUsernameList(); ### *See Also* -- [Singleton Pattern](../19%20Misc/Design%20Patterns.md#singleton-pattern) +- [Singleton Pattern](<../../19 Misc/Design Patterns.md#singleton-pattern>) ## Annotation 기반 설정 사용 시 주의점 diff --git a/content/10 Wiki/13 Spring/13.04 MVC.md b/content/10 Wiki/13 Spring/13.04 MVC/index.md similarity index 99% rename from content/10 Wiki/13 Spring/13.04 MVC.md rename to content/10 Wiki/13 Spring/13.04 MVC/index.md index 553eefb..bc5ed0c 100644 --- a/content/10 Wiki/13 Spring/13.04 MVC.md +++ b/content/10 Wiki/13 Spring/13.04 MVC/index.md @@ -7,7 +7,7 @@ tags: ## [`DispatcherServlet`](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/DispatcherServlet.html) -![MVC Context Hierarchy](<../../00 Meta/02 Images/mvc-context-hierarchy.png>) +![MVC Context Hierarchy](mvc-context-hierarchy.png)g Spring MVC는 `DispatcherServlet`이 애플리케이션의 중심에서 요청 처리를 위해 공유되는 알고리즘을 제공하고 실제 동작은 따로 설정 가능한 대리 컴퍼넌트가 하게 되는 [front controller](https://en.wikipedia.org/wiki/Front_controller) 패턴으로 설계되었다. diff --git a/content/00 Meta/02 Images/mvc-context-hierarchy.png b/content/10 Wiki/13 Spring/13.04 MVC/mvc-context-hierarchy.png similarity index 100% rename from content/00 Meta/02 Images/mvc-context-hierarchy.png rename to content/10 Wiki/13 Spring/13.04 MVC/mvc-context-hierarchy.png diff --git a/content/10 Wiki/19 Misc/Computer Networks.md b/content/10 Wiki/19 Misc/Computer Networks.md index 7e9c34e..c144a9d 100644 --- a/content/10 Wiki/19 Misc/Computer Networks.md +++ b/content/10 Wiki/19 Misc/Computer Networks.md @@ -113,7 +113,7 @@ RTO, DupAck 기반 재전송 기술로 신뢰성이 확보되어 있다. ### URL & URI -![URL](../../00%20Meta/02%20Images/mdn-url-all.png) +![URL](<./HTML & CSS/mdn-url-all.png> - [URL](https://en.wikipedia.org/wiki/URL) - [Uniform Resource Identifier](https://en.wikipedia.org/wiki/Uniform_Resource_Identifier) diff --git a/content/00 Meta/02 Images/css-flex.png b/content/10 Wiki/19 Misc/HTML & CSS/css-flex.png similarity index 100% rename from content/00 Meta/02 Images/css-flex.png rename to content/10 Wiki/19 Misc/HTML & CSS/css-flex.png diff --git a/content/10 Wiki/19 Misc/HTML & CSS.md b/content/10 Wiki/19 Misc/HTML & CSS/index.md similarity index 99% rename from content/10 Wiki/19 Misc/HTML & CSS.md rename to content/10 Wiki/19 Misc/HTML & CSS/index.md index 4c5ba26..908f55d 100644 --- a/content/10 Wiki/19 Misc/HTML & CSS.md +++ b/content/10 Wiki/19 Misc/HTML & CSS/index.md @@ -397,7 +397,7 @@ div { - 위와 같이 적음으로써 부모 요소는 flex container가 되고 flexbox 관련 속성을 적용할 수 있다. - 자식 요소들은 flex item이라고 부른다. -![CSS Flexbox](../../00%20Meta/02%20Images/css-flex.png) +![CSS Flexbox](./css-flex.png) #### Flex container 속성들 diff --git a/content/00 Meta/02 Images/mdn-url-all.png b/content/10 Wiki/19 Misc/HTML & CSS/mdn-url-all.png similarity index 100% rename from content/00 Meta/02 Images/mdn-url-all.png rename to content/10 Wiki/19 Misc/HTML & CSS/mdn-url-all.png diff --git a/content/00 Meta/02 Images/docker.png b/content/20 Posts/2023-09-30 Docker on Mac/docker.png similarity index 100% rename from content/00 Meta/02 Images/docker.png rename to content/20 Posts/2023-09-30 Docker on Mac/docker.png diff --git a/content/20 Posts/2023-09-30 Docker on Mac.md b/content/20 Posts/2023-09-30 Docker on Mac/index.md similarity index 98% rename from content/20 Posts/2023-09-30 Docker on Mac.md rename to content/20 Posts/2023-09-30 Docker on Mac/index.md index bc06a26..e08f1cd 100644 --- a/content/20 Posts/2023-09-30 Docker on Mac.md +++ b/content/20 Posts/2023-09-30 Docker on Mac/index.md @@ -17,7 +17,7 @@ Windows를 사용할 때는 [**WSL**](https://learn.microsoft.com/en-us/windows/ ## Docker Desktop -![docker](../00%20Meta/02%20Images/docker.png) +![docker](docker.png) Docker를 Mac에서 사용하는 공식적인 방법은 Docker Desktop을 설치하는 것이다. 내 맨 처음 세팅도 Docker Desktop이었다. @@ -31,7 +31,7 @@ Docker 공식 툴이고 GUI와 Kubernetes 등 다양한 기능을 가지고 있 ## Podman -![podman](../00%20Meta/02%20Images/podman.png) +![podman](podman.png) 앞서 말한 이유 때문에 Docker Desktop을 사용하지 않고 Docker Engine CLI를 사용하는 방법이 없을까 하다가 발견한 것이 [**Podman**](https://podman.io/)이다. Podman은 Docker와 호환되는 별개의 툴로 Red Hat에서 개발을 시작한 오픈 소스 컨테이너 관리 툴이다. @@ -99,7 +99,7 @@ Mac에도 공식적으로 지원하는 [**Virtualization framework**](https://de ## Lima -![lima](../00%20Meta/02%20Images/lima.png) +![lima](lima.png) Visual Studio Code의 Docker 확장 프로그램이 몇 번 업데이트 되고 난 이후에도 Podman과 호환되지 않아서 해당 확장 프로그램 repository의 issue들을 살펴보던 중 [**nerdctl**](https://github.com/containerd/nerdctl)이라는 툴도 있다는 것을 알게 되었다. 해당 툴도 현재 호환이 되지 않는 상태였다. @@ -137,7 +137,6 @@ limactl start # VM 종료 limactl stop - ``` Docker 템플릿을 VM으로 만들고 이름을 `default`로 설정해서 기본 VM으로 지정해주었다. diff --git a/content/00 Meta/02 Images/lima.png b/content/20 Posts/2023-09-30 Docker on Mac/lima.png similarity index 100% rename from content/00 Meta/02 Images/lima.png rename to content/20 Posts/2023-09-30 Docker on Mac/lima.png diff --git a/content/00 Meta/02 Images/podman.png b/content/20 Posts/2023-09-30 Docker on Mac/podman.png similarity index 100% rename from content/00 Meta/02 Images/podman.png rename to content/20 Posts/2023-09-30 Docker on Mac/podman.png diff --git a/content/20 Posts/2024-10-04 Gemma Sprint/index.md b/content/20 Posts/2024-10-04 Gemma Sprint/index.md new file mode 100644 index 0000000..7bda595 --- /dev/null +++ b/content/20 Posts/2024-10-04 Gemma Sprint/index.md @@ -0,0 +1,126 @@ +--- +tags: + - AI + - LLM + - Gemma + - MLX + - LangChain + - GemmaSprint +--- +# Gemma 2를 활용한 Read-it-later 목록 항목 요약하기 + +**Google for Developers Machine Learning Bootcamp 2024** 프로그램에 참가하면서 **Gemma**를 활용한 프로젝트, **Gemma Sprint**를 진행했다. 평소에 관심 있는 최신 논문, 블로그 포스트, 뉴스 등을 스크랩해서 PDF 문서 파일이나 HTML 스냅샷 파일과 함께 Read-it-later 목록을 저장해두고 있었는데 제목만 봐서는 내용을 바로 파악하기 힘든 경우가 있었다. 그렇다고 매번 직접 훑어보기도 힘들어서 LLM을 사용하여 각 항목의 요약을 만들면 좋겠다는 생각이 들어서 여기에 **Gemma 2**를 활용해보기로 했다. *#GemmaSprint* + + + +## Gemma 2 2B Instruction-tuned Model + +이번 Gemma Sprint에서는 로컬 환경에서 사용할 수 있는 비교적 작은 크기의 오픈 모델인 **Gemma 2 2B** 모델을 사용했다. 별도의 fine-tuning, instruction-tuning을 하지 않고 Google이 제공하는 **instruction-tuned** model을 활용하기로 했다. [**Hugging Face**에서](https://huggingface.co/google/gemma-2-2b-it) model card를 확인할 수 있고 model weight와 tokenizer도 쉽게 다운로드받을 수 있다. + +## [MLX](https://github.com/ml-explore/mlx) + +앞서 말했듯 Gemma 2 2B 모델은 로컬환경에서 사용할 수 있을 만큼 크기가 작다. 내가 현재 주로 사용하는 개발 환경인 M1 MacBook Air에서도 충분히 실행가능한 크기다. 다만 Apple silicon을 사용하기 때문에 주로 많이 사용되는 Nvidia GPU의 CUDA를 사용할 수가 없다. 그렇기 때문에 TensorFlow, PyTorch, JAX 같이 주로 사용되는 ML 프레임워크를 사용할 때 다소 성능이 아쉽지만 CPU 상에서 연산하도록 하거나 GPU를 활용하기 위해 추가적인 설정이 필요하다. + +이런 번거로움에서 쉽게 벗어날 수 있는 방법이 바로 **MLX**다. MLX는 작년 말 Apple에서 출시한 Apple silicon용 ML 프레임워크다. Apple에서 직접 만든 프레임워크인 만큼 Apple silicon의 CPU, GPU에 최적화되어있어 별 다른 설정없이 좋은 성능을 기대할 수 있다. [Hugging Face에서](https://huggingface.co/mlx-community/quantized-gemma-2b-it) MLX 포맷으로 변경된 Gemma 2 2B 모델의 weight, tokenizer를 확인, 다운로드할 수 있다. + +## [LangChain](https://github.com/langchain-ai/langchain) + +MLX를 활용하면 모델에 프롬프트를 입력하고 모델이 응답이 출력하게 하는 데까지는 간단하게 구현할 수 있다. 하지만 PDF, HTML 등을 불러와서 적당한 프롬프트와 함께 입력해서 모델이 그럴듯한 요약을 출력할 수 있게 하는 하나의 앱을 구현하는 것은 상당히 번거로울 수 있다. 이 과정을 좀 더 편하게 할 수 있게 해주는 프레임워크 **LangChain**이다. + +LangChain의 다양한 서드파티 통합 기능을 활용하면 [MLX을 LLM agent로 연결](https://python.langchain.com/docs/integrations/chat/mlx/)하고 [PDF](https://python.langchain.com/docs/how_to/document_loader_pdf/), [HTML](https://python.langchain.com/docs/how_to/document_loader_web/)을 문서로 불러오는 과정을 쉽게 할 수 처리할 수 있다. [**LangGraph**](https://github.com/langchain-ai/langgraph) 라이브러리와 함께 사용하면 크기가 큰 문서를 모델이 처리할 수 있는 크기로 분리한 후 요약하고 다시 하나의 요약으로 합치는 과정도 그래프화해서 구현할 수 있다[^1]. + +## Implementation + +기본적으로 원하는 동작은 Python 스크립트에 인수로 PDF나 HTML 파일의 경로를 입력하면 이를 요약해서 출력해주는 것이다. 원래는 현재 Read-it-later 목록을 관리하기 위해 사용 중인 Zotero와 통합시켜서 일괄적으로 읽어서 요약시키는 과정까지도 구현해보려고 했으나 일단 위에 설명한 기본적인 기능만 구현하면 따로 추가적인 스크립트를 작성해서 실행시켜도 되는 부분이라서 일단은 기본적인 동작까지만 구현하는 것으로 생각하고 진행했다. + +자세한 코드는 [이 프로젝트의 GitHub repository](https://github.com/jmkim0/ril-summarizer)에서 확인할 수 있다. + +## Examples + +### PDF 요약 + +최근에 스크랩한 [Secure by Design at Google](https://research.google/pubs/secure-by-design-at-google/) 논문을 요약해보았다. + +#### CLI 출력 + +```bash +$ python ril_summarizer.py "Kern - Secure by Design at Google.pdf" +Generated 8 documents. +None of PyTorch, TensorFlow >= 2.0, or Flax have been found. Models won't be available and only tokenizers, configuration and file/data utilities can be used. +Fetching 7 files: 100%|████████████████████████████████████████████████████████████████| 7/7 [00:00<00:00, 78713.48it/s] +['generate_summary'] +['generate_summary'] +['generate_summary'] +['generate_summary'] +['generate_summary'] +['generate_summary'] +['generate_summary'] +['generate_summary'] +/Users/jmkim/Projects/ril-summarizer/venv/lib/python3.12/site-packages/transformers/tokenization_utils_base.py:1617: FutureWarning: `clean_up_tokenization_spaces` was not set. It will be set to `True` by default. This behavior will be deprecated in transformers v4.45, and will be then set to `False` by default. For more details check this issue: https://github.com/huggingface/transformers/issues/31884 + warnings.warn( +['collect_summaries'] +['collapse_summaries'] +['collapse_summaries'] +['generate_final_summary'] +# 이후 최종 요약 출력 +``` + +#### 최종 요약 출력 + +> **Main Themes:** +> +> - Design thinking and security are essential for software development. +> - Prevention of vulnerabilities is crucial to ensure software security. +> - Security design principles should be prioritized from the outset. +> - Memory safety, secure design principles, and vulnerability prevention are important considerations. +> - Thorough testing and code review are crucial for ensuring security. +> - Developers have a responsibility to prioritize security throughout the development process. + +어떤 내용을 담고 있는 지는 확인할 수 있을 정도로 정제된 요약을 보여주고 있음을 확인할 수 있다. + +### HTML 요약 + +최근의 스크랩한 Reuters의 뉴스 기사 [If your AI seems smarter​, it's thanks to smarter human trainers](https://www.reuters.com/technology/artificial-intelligence/if-your-ai-seems-smarter-its-thanks-smarter-human-trainers-2024-09-28/)를 요약해보았다. + +#### CLI 출력 + +```bash +$ python ril_summarizer.py "/Users/jmkim/Zotero/storage/LHISV6V9/if-your-ai-seems-smarter-its-thanks-smarter-human-trainers-2024-09-28.html" +Generated 2 documents. +None of PyTorch, TensorFlow >= 2.0, or Flax have been found. Models won't be available and only tokenizers, configuration and file/data utilities can be used. +Fetching 7 files: 100%|████████████████████████████████████████████████████████████████| 7/7 [00:00<00:00, 84368.18it/s] +['generate_summary'] +['generate_summary'] +/Users/jmkim/Projects/ril-summarizer/venv/lib/python3.12/site-packages/transformers/tokenization_utils_base.py:1617: FutureWarning: `clean_up_tokenization_spaces` was not set. It will be set to `True` by default. This behavior will be deprecated in transformers v4.45, and will be then set to `False` by default. For more details check this issue: https://github.com/huggingface/transformers/issues/31884 + warnings.warn( +['collect_summaries'] +['generate_final_summary'] + +``` + +#### 최종 요약 출력 + +> Sure, here's a final summary of the main themes: +> +> - Human trainers play a crucial role in shaping the intelligence of artificial intelligence (AI) models by providing human feedback and specialized knowledge. +> +> +> - AI often requires superior training and specialized knowledge to create accurate and reliable AI models. +> +> +> - Invisible Tech, a startup specializing in AI training, employs thousands of trainers worldwide to provide human feedback to AI models. +> +> +> - As AI models become more advanced, the demand for specialized trainers and across dozens of languages is on the rise. + +출력 형식이 살짝 달라졌지만 그럴듯한 요약을 만들어주는 것을 확인할 수 있다. + +## 결론 + +Gemma 2 2B 모델을 활용하여 PDF, HTML 문서를 요약하는 Python 스크립트를 만들어본 결과 상당히 그럴듯한 결과물을 얻을 수 있었다. MLX 포맷 기준 2 GB를 좀 넘는 크기의 작은 모델로 로컬 환경에서 추론한 것임을 감안하면 대단히 만족스럽다. 다만 페이지가 많은 문서에도 시험해본 결과 실행 시간이 상당히 길어지는 것을 확인할 수 있어서 긴 논문의 경우 차라리 Abstract만 추출해서 요약하는 등 문서의 종류에 따라 적절한 동작을 할 수 있게 하면 좋을 것 같다. + +일반적인 동작을 할 수 있게 instruction-tuning된 모델을 사용해서 개발 과정이 간소해지긴 했지만 출력 형식이 일정하지 않는 등 무작위성이 드러나기도 했다. 이부분을 base 모델을 요약 기능 전용으로 fine-tuning 함으로써 개선할 수 있을지 궁금하기도 한데 사실상 현재 구현으로도 원래 의도했던 훑어보는 용도의 요약은 잘 만들어주고 있는 것 같아서 오버엔지니어링이 아닐까 싶다. + +점점 기술이 발전하면서 LLM 자체의 크기도 커지고 그 성능도 대단해지고 있지만 Gemma 2 2B처럼 효율이 좋고 작은 LLM도 오픈 모델로 나오고 있다. API에 비용을 지불하고 활용할 수도 있지만 로컬에서 활용할 수 있는 작고 효율적인 오픈 모델의 활용도 익혀두면 작업의 특성에 따라 다르게 활용한다는 선택지도 가져갈 수 있어 좋을 것 같다. 물론 선택지 간의 결정에는 API 사용료와 엔지니어링 비용의 trade-off도 고려해야겠지만 말이다. + +[^1]: https://python.langchain.com/docs/tutorials/summarization/