├── Open-source_LLM ├── basic_chat │ ├── huggingface_LLM_chat.ipynb │ ├── langchain_ollama_QnA.ipynb │ ├── langchain_ollama_chatbot.ipynb │ └── langchain_ollama_prompting.ipynb └── rag │ ├── llama-index_huggingface_RAG_basic.ipynb │ └── llama-index_ollama_RAG_basic.ipynb ├── OpenAI ├── OpenAI_API_call.ipynb ├── OpenAI_RAG_ChatAPI.ipynb └── OpenAI_RAG_Llama_index.ipynb └── README.md /Open-source_LLM/basic_chat/langchain_ollama_QnA.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# **Langchain과 Ollama를 이용한 Q&A 시스템 예제**\n", 8 | "\n", 9 | "**Langchain**과 **Ollama**를 이용해 **Open-source LLM**으로 Q&A 시스템을 만드는 예제입니다.\n", 10 | "\n", 11 | "\n", 12 | "*본 예제는 구글 코랩 환경이 아닙니다." 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": {}, 18 | "source": [ 19 | "## **1. 환경 세팅**\n", 20 | "- 개발 환경에 필요 라이브러리 설치 : ollama, langchain, langchain_community,...\n", 21 | "- 필요 패키지 임포트\n", 22 | "- Ollama 모델 사용 방법" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": 1, 28 | "metadata": {}, 29 | "outputs": [], 30 | "source": [ 31 | "# 필요한 라이브러리 임포트\n", 32 | "from langchain_community.llms import Ollama\n", 33 | "from langchain_core.prompts import PromptTemplate\n", 34 | "from langchain.chains import LLMChain\n", 35 | "from IPython.display import Markdown, display" 36 | ] 37 | }, 38 | { 39 | "attachments": { 40 | "image.png": { 41 | "image/png": "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3VzlUVW1x2DP8mq0WlLduzd1b/u+wH31NfY12/br7C89AA5IDjw/mHbw5qHwQ02HGYdrjlgcqThKO1pSi9ROr+2vy6rrqk+u72gIa2hq9G48eszh2K7jJsfLT2ifWH6ScnLhycFTRacGTotO953JPPO4aVLT3bPjzl5vjmluOxd+7sL54PNnW5gtpy74XDh+0etiwyXGpbrL7pdrW91aj/7u9vvRNve22iseV+rbPdsbO8Z0nLzqd/XMtcBr56+zr1++EXmj42bCzVudqZ1dt3i3em7n3n51p/DO57tz7xHuldxXv1/2wOBB5R82f+zvcu868TDwYeujuEd3H3Mfv3iS/+RL98Kn1Kdlz4yfVfU49xzvDe5tfz7+efcL0YvPfcV/avxZ8dL65ZG//P9q7R/X3/1K/Grw9dI3em92vXV92zQQPfDgXd67z+9LPuh92P2R8bHlU9KnZ5+nfiF9Wf/V5mvjt/Bv9wbzBgdFHDFH9iuAwYpmZADwehcA1GQAaPB8RhkvP//JCiI/s8oQ+E9YfkaUFXcAauD/e0wf/LvpBODADnj8gvpqqQBEUwGI9wSoi8twHTqryc6V0kKE54Ct8V/T89LBvynyM+cPcf/cAqmqK/i5/RcGNXx6Q6zySgAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAGtKADAAQAAAABAAADfAAAAAAkkNlyAABAAElEQVR4AezdB5wcVf0A8BdIIKEnAZJQE3oVlSqCAtI7SO9VmoACSvsjSJUmIiKogIig0kKRJtKl907okARIAqElIQFS/vubZJa9uy13uUtuL/d9n89lZt578+bNd2Z389nfvjddJhVSkggQIECAAAECBAgQIECAAAECBAgQIECAAAECBAjUqcBMddov3SJAgAABAgQIECBAgAABAgQIECBAgAABAgQIECCQCQhouREIECBAgAABAgQIECBAgAABAgQIECBAgAABAgTqWkBAq64vj84RIECAAAECBAgQIECAAAECBAgQIECAAAECBAgIaLkHCBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIE6lpAQKuuL4/OESBAgAABAgQIECBAgAABAgQIECBAgAABAgQICGi5BwgQIECAAAECBAgQIECAAAECBAgQIECAAAECBOpaQECrri+PzhEgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECAhouQcIECBAgAABAgQIECBAgAABAgQIECBAgAABAgTqWkBAq64vj84RIECAAAECBAgQIECAAAECBAgQIECAAAECBAgIaLkHCBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIE6lpAQKuuL4/OESBAgAABAgQIECBAgAABAgQIECBAgAABAgQICGi5BwgQIECAAAECBAgQIECAAAECBAgQIECAAAECBOpaQECrri+PzhEgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECAhouQcIECBAgAABAgQIECBAgAABAgQIECBAgAABAgTqWkBAq64vj84RIECAAAECBAgQIECAAAECBAgQIECAAAECBAgIaLkHCBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIE6lpAQKuuL4/OESBAgAABAgQIECBAgAABAgQIECBAgAABAgQICGi5BwgQIECAAAECBAgQIECAAAECBAgQIECAAAECBOpaQECrri+PzhEgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECAhouQcIECBAgAABAgQIECBAgAABAgQIECBAgAABAgTqWkBAq64vj84RIECAAAECBAgQIECAAAECBAgQIECAAAECBAgIaLkHCBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIE6lpAQKuuL4/OESBAgAABAgQIECBAgAABAgQIECBAgAABAgQICGi5BwgQIECAAAECBAgQIECAAAECBAgQIECAAAECBOpaQECrri+PzhEgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECHSdEQm+GDs2jRg+In0wbFgaNmx4GjV6dJq3d6/Up0+f1Lfw16fP/Klr1xny1GfEy+mcCBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgU4uMENEdd566+10zXXXp4ceeiS9/c67acyYMTUva+/evdNii/VPm2y0Ydp66y1Tz3nmqblPcyucfsZZ6f0PhlWsvukmG6ZNN9m4bPlzzz2f/nLp5WXLIrNbt27pjNN+nbp3716xjgICBAgQIECAAAECBAgQIECAAAECBAgQIECAwIwk0GVSIXXEE/r666/TXXffk6686l/p4UcebfUpbPfjbdJOO26fVv7ud1rd1iqrr5VGjhxZsZ19994z/d/xx5QtH3jD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x55IDz3ySHrmmedqTltZsX8KCBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgaJAXQW05pprzmLHKq1EIGbChAlp5plnrlSl1fnDhg+v2UafPn1q1mnvChHEuvTSy9Nd99yb3n77nfbuzgx5/Bjpdsd/7kzXXX9Duufe+2fIc3RSBAgQIECAAAECBAgQIECAAAECBAgQIECgvQXqKqAVU/jFVH61Rg8988yzaZVVVp5mdg89XHuqvb595p9mx29twxHw+/NfLktnnfPb1jZl/yoCgwa9mk448eT05FNPV6mliAABAgQIECBAgAABAgQIECBAgAABAgQIEGitwEytbaCt9+/Tt3ag6J77pu1ImDvuuLPmadXrlINff/11OuxnRwlm1byCrasQ0zdusvnWglmtY7Q3AQIECBAgQIAAAQIECBAgQIAAAQIECBBolkDdBbRWXGH5mh2/9dY7ataZ2gpDhg5Nr7/xZs3dl112mZp1pneFmP7u8J8flW67fdr5TO9zqsfjPfvc82mHnXerx67pEwECBAgQIECAAAECBAgQIECAAAECBAgQmCEF6mrKwRDeZOON0mV/vaIqdkxJ+Morg9K0CCo1Z3TW7LPPntZYfbWqfWyPwocffjTd3ozRZXnf4jwigNivX98011xzpbnnnitbzjXnnGnOwl8E904/46y8uuUUgdNOP7NFFgMG9E9LLblE6tmzZwPjMJ9jjjkKI+qOTGPGjGlRmyoTIECAAAECBAgQIECAAAECBAgQIECAAIHOJFB3Aa3vfufbqXfv3mnkyJFVr8PJp56R/nHl5Smeu9VW6aOPRqbzL/hjzea22XrL1K1bt5r1pneFP/zx4mYd8oCf7Jv22G3XtMAC/arWf/XV19LpVWt0vsLHHn+iWdMMrrD8cunnPzssfX/NNdKss85aFeqHP1jbqLqqQgoJECBAgAABAgQIECBAgAABAgQIECBAoLML1N2UgzPNNFPafrttal6XRx97PN1y6+0167WkwjnnnteskTKbbbpxS5qdLnWHDR+ewqRWuu3fN6RjfnlUzWBWtPPF2LG1mut05c255yLgefON16X11v1hzWBWAI4ePbrTOTphAgQIECBAgAABAgQIECBAgAABAgQIECDQEoG6C2hF5zfZaMNmncOvTzk9ffrpZ82qW6vSk08+la6+9vpa1bLRY6uusnLNetO7wtCh79U85Cm//lWLpmkcMmRozTY7W4V33n236inH6MLTT/11i0YOvvb6G1XbVEiAAAECBAgQIECAAAECBAgQIECAAAECBDq7QF0GtFZccYW0yMIL17w2MS3hDjvtmoaPGFGzbrUKEczaa98DqlUplm295eZp5plnLm7Xy8rQwvOuaqXVVlu1VpUG5f+5864G2zZSeuONt6oyxLPVunfvXrVOaWFM6zhs2LDSLOsECBAgQIAAAQIECBAgQIAAAQIECBAgQIBAI4G6DGjFc7FOPOG4Rl0tv/n6G2+mrbfdMb07eHD5CjVy77v/gbT9Trs1a6rB2WefPR14wP41Wmyf4nHjvqx54K+//rpmnbzCSy+/4rlOOUbJctSoUSVbTVe/+uqrppkVciZOnJh+/4eLKpTKJkCAAAECBAgQIECAAAECBAgQIECAAAECBHKBugxoRefWW2+dtOP2P47VmilGuGy2xbbpwov+1OwpCN966+103P+dmPZu5sis6MQ5Z52R5p23d83+tEeF+eefv+Zh77773pp1osLjTzyZdtx592bV7WyVBvRftOopP/zIo+mTTz6pWicKv/zyy3TEUUcLGtaUUoEAAQIECBAgQIAAAQIECBAgQIAAAQIECKRUtwGtuDjHH3d06tu3b7Ou05gxY9I55/4ufWeVNdLpZ5yV7n/gf+nNN99KY8eOy/b/7LPPU4w6imn0Djn05+lHG26a/vmva5rVdlTaeqst08YbbdDs+tO74gL9ajudd/4F6c7/3l21a7fcensWzApPqanAIoss0jSzJCfcDjj40PTFF1+U5DZcjXtxr31+km66+ZaGBbYIECBAgAABAgQIECBAgAABAgQIECBAgACBsgJdy+bWSeacc86Zzj37jLTr7nu3qEd/ufSvKf7aKvXu3Tud9Kvj26q5adLOootWHzmUH/SAg36afrD2Wmn33XbOnlM219xzpU8/+TS9MujVNPDGm9KDDz6cV7UsI7DiCsvXHFX1xBNPpdW+94N08EE/SasXnlvWpzB6buKkiYVnZQ1P99x7X7ru+htTPP9NIkCAAAECBAgQIECAAAECBAgQIECAAAECBJonUNcBrTiFNb+3Rvr54YemGF3UXunCC85LcxcCP/WcevTonvbbZ690yWWX1+zmA/97MMWf1HKBH2+7dTrz7HNr7hgjtc4+57ya9VQgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEagvU9ZSDefcPO/TgdP555+Sb0225yMILp//c/u9slM10O2grDrTbrju3Yu+mu84+++xNMzt5znzzzdvsZ7t1ciqnT4AAAQIECBAgQIAAAQIECBAgQIAAAQIE2kygQwS04my33GKz9O+brm/2M7VaKxTT8t10w7VpqSWXaG1T023/RRddJP3m9FPa5HgRzLvskovbpK0ZrZHjjj06DRjQv01O69STT0ybbrJxm7SlEQIECBAgQIAAAQIECBAgQIAAAQIECBAgMKMKdJiAVlyAFZZfLt1y03VpjdVXm6bX4yf775sFc+aZZ+5pepxp0fiOO2yXDvjJvq1qOkZm/fXSP6W556rvaRZbdZKt2HmuueZMf73kTymerdaaFCPqdt1lp9Y0YV8CBAgQIECAAAECBAgQIECAAAECBAgQINApBDpUQCuuSAQR/nHl5enqf/49bbXl5m12kSKIc9CB+6f77v5POvboo9LMM8/cZm1P74aO+eVRKZ77NTVTBm73423S3f+9LS222IDp3e0OdbwYDXfn7TenTTbesMX97tu3b3Z9Tj7phBbvawcCBAgQIECAAAECBAgQIECAAAECBAgQINAZBbp2xJPu0qVLWm3VVbK/E44/Jg288eZ05ZX/TIOHDGnx6ay66spp9113SRtu8KM066yztnj/cjvECJ6RI0eWK8ryZp+j8rOpevToXnG/vKBr19qXLaaxW3WVVdLV116XBt5wU3r77Xfy3csuY9RbBPK+9a0Vi+Xdu9fuS/cK/e3RY7ZiO5VWunXrVqmoSX6l4+QVm9PXvG4sZ+vRo3Sz7HrcZ9VSr1690h//cH667/4H0nXX35huve32atWzAGMETffZa89Uep3nqHI/RIPV7peqB1RIgAABAgQIECBAgAABAgQIECBAgAABAgRmEIEukwppRjiXiRMnphEjRqQPhg1Pwwp/H3wwrPD3QXrv/fcLgarJgZkF+vVNCyzQL/UrjJDp07dPYdknRVCiM6RXX30tC/iNGPFh+mLs2BTBmgUXWCAtvvhiqX9htNEss8zSGRim6TmOGjUqvfDiS9l9GM4RII2g3RJLLJ4G9O+f5ptv3ml6fI0TIECAAAECBAgQIECAAAECBAgQIECAAIEZVWCGCWjNqBfIeREgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEOrtAh3uGVme/YM6fAAECBAgQIECAAAECBAgQIECAAAECBAgQINDZBAS0OtsVd74ECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgQ4mIKDVwS6Y7hIgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEOpuAgFZnu+LOlwABAgQIECBAgAABAgQIECBAgAABAgQIECDQwQQEtDrYBdNdAgQIECBAgAABAgQIECBAgAABAgQIECBAgEBnExDQ6mxX3PkSIECAAAECBAgQIECAAAECBAgQIECAAAECBDqYgIBWB7tgukuAAAECBAgQIECAAAECBAgQIECAAAECBAgQ6GwCAlqd7Yo7XwIECBAgQIAAAQIECBAgQIAAAQIECBAgQIBABxMQ0OpgF0x3CRAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQKdTUBAq7NdcedLgAABAgQIECBAgAABAgQIECBAgAABAgQIEOhgAgJaHeyC6S4BAgQIECBAgAABAgQIECBAgAABAgQIECBAoLMJCGh1tivufAkQIECAAAECBAgQIECAAAECBAgQIECAAAECHUxAQKuDXTDdJUCAAAECBAgQIECAAAECBAgQIECAAAECBAh0NgEBrc52xZ0vAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKCDCQhodbALprsECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgc4mIKDV2a648yVAgAABAgQIECBAgAABAgQIECBAgAABAgQIdDABAa0OdsF0lwABAgQIECBAgAABAgQIECBAgAABAgQIECDQ2QQEtDrbFXe+BAgQIECAAAECBAgQIECAAAECBAgQIECAAIEOJiCg1cEumO4SIECAAAECBAgQIECAAAECBAgQIECAAAECBDqbgIBWZ7vizpcAAQIECBAgQIAAAQIECBAgQIAAAQIECBAg0MEEBLQ62AXTXQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIBAZxMQ0OpsV9z5EiBAgAABAgQIECBAgAABAgQIECBAgAABAgQ6mICAVge7YLpLgAABAgQIECBAgAABAgQIECBAgAABAgQIEOhsAgJane2KO18CBAgQIECAAAECBAgQIECAAAECBAgQIECAQAcTENDqYBdMdwkQIECAAAECBAgQIECAAAECBAgQIECAAAECnU1AQKuzXXHnS4AAAQIECBAgQIAAAQIECBAgQIAAAQIECBDoYAICWh3sgukuAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKCzCQhodbYr7nwJECBAgAABAgQIECBAgAABAgQIECBAgAABAh1MQECrg10w3SVAgAABAgQIECBAgAABAgQIECBAgAABAgQIdDYBAa3OdsWdLwECBAgQIECAAAECBAgQIECAAAECBAgQIECggwkIaHWwC6a7BAgQIECAAAECBAgQIECAAAECBAgQIECAAIHOJiCg1dmuuPMlQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECHQwAQGtDnbBdJcAAQIECBAgQIAAAQIECBAgQIAAAQIECBAg0NkEutbDCb/73oh66IY+ECBAgAABAgQIECBAgAABAgQIECBAgAABAgQITKXAogvOP5V71t7NCK3aRmoQIECAAAECBAgQIECAAAECBAgQIECAAAECBAi0o0CXSYXUjsd3aAIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQJVBYzQqsqjkAABAgQIECBAgAABAgQIECBAgAABAgQIECBAoL0FBLTa+wo4PgECBAgQIECAAAECBAgQIECAAAECBAgQIECAQFUBAa2qPAoJECBAgAABAgQIECBAgAABAgQIECBAgAABAgTaW0BAq72vgOMTIECAAAECBAgQIECAAAECBAgQIECAAAECBAhUFRDQqsqjkAABAgQIECBAgAABAgQIECBAgAABAgQIECBAoL0FBLTa+wo4PgECBAgQIECAAAECBAgQIECAAAECBAgQIECAQFUBAa2qPAoJECBAgAABAgQIECBAgAABAgQIECBAgAABAgTaW0BAq72vgOMTIECAAAECBAgQIECAAAECBAgQIECAAAECBAhUFRDQqsqjkAABAgQIECBAgAABAgQIECBAgAABAgQIECBAoL0FBLTa+wo4PgECBAgQIECAAAECBAgQIECAAAECBAgQIECAQFUBAa2qPAoJECBAgAABAgQIECBAgAABAgQIECBAgAABAgTaW0BAq72vgOMTIECAAAECBAgQIECAAAECBAgQIECAAAECBAhUFRDQqsqjkAABAgQIECBAgAABAgQIECBAgAABAgQIECBAoL0FBLTa+wo4PgECBAgQIECAAAECBAgQIECAAAECBAgQIECAQFUBAa2qPAoJECBAgAABAgQIECBAgAABAgQIECBAgAABAgTaW0BAq72vgOMTIECAAAECBAgQIECAAAECBAgQIECAAAECBAhUFRDQqsqjkAABAgQIECBAgAABAgQIECBAgAABAgQIECBAoL0FBLTa+wo4PgECBAgQIECAAAECBAgQIECAAAECBAgQIECAQFUBAa2qPAoJECBAgAABAgQIECBAgAABAgQIECBAgAABAgTaW0BAq72vgOMTIECAAAECBAgQIECAAAECBAgQIECAAAECBAhUFRDQqsqjkAABAgQIECBAgAABAgQIECBAgAABAgQIECBAoL0FBLTa+wo4PgECBAgQIECAAAECBAgQIECAAAECBAgQIECAQFUBAa2qPAoJECBAgAABAgQIECBAgAABAgQIECBAgAABAgTaW0BAq72vgOMTIECAAAECBAgQIECAAAECBAgQIECAAAECBAhUFRDQqsqjkAABAgQIECBAgAABAgQIECBAgAABAgQIECBAoL0FBLTa+wo4PgECBAgQIECAAAECBAgQIECAAAECBAgQIECAQFUBAa2qPAoJECBAgAABAgQIECBAgAABAgQIECBAgAABAgTaW0BAq72vgOMTIECAAAECBAgQIECAAAECBAgQIECAAAECBAhUFRDQqsqjkAABAgQIECBAgAABAgQIECBAgAABAgQIECBAoL0FBLTa+wo4PgECBAgQIECAAAECBAgQIECAAAECBAgQIECAQFUBAa2qPAoJECBAgAABAgQIECBAgAABAgQIECBAgAABAgTaW6Bre3eg8fFv+c+o9NRz49IHH3ydJkzsktKkSSkVFpNTrBS2i6k+yr/+/Lhij6xMe4GuXbumfv36pdVWWy1tscUW0/6AjkCAAAECBAgQIECAAAECBAgQIECAAAECBAi0q0CXSYXUrj2YcvDhI8ani/76cRo69OuSAFahMHpXDGjV57aA1pSL2A6LRRZZJB1yyCGpb9++7XB0hyRAgAABAgQIECBAgAABAgQIECBAgAABAgSmh0DdTDmYBbPeKwSzJAItEBg8eHC68MILW7CHqgQIECBAgAABAgQIECBAgAABAgQIECBAgEBHE6iLgNYtd4xKQ4Z+lc0uOKkwJCvGjMXAsWzZIbajr5MHuk3ut+3p6fHuu++mm2++uaO99vSXAAECBAgQIECAAAECBAgQIECAAAECBAgQaKZAXQS0nnx2bDO7W5/VunQpnROxMEOi7QYXanp4PP744w2OaYMAAQIECBAgQIAAAQIECBAgQIAAAQIECBCYcQS61sOpvPd+jM7KH+VVbpnnRW/z9dJlvt4+5RMnTswY83OwnHw9pqfDe++9l10D/xAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIznkBdjNCaMDkeVEW34QiophXbu7xpj+RMX4Hx48dP3wM6GgECBAgQIECAAAECBAgQIECAAAECBAgQIDDdBOoioBUjeZr+5c/RKlcWefVTHldreo5GcrzK3tPtleNABAgQIECAAAECBAgQIECAAAECBAgQIECAwHQTqIuA1uSzbe9RVq09/nS7Zg5EgAABAgQIECBAgAABAgQIECBAgAABAgQIEOhUAnXxDK3Jo5viuUsRVMqfh9Xy7WWW6pGWWXLWdOOtn01pp2l7yyw1a9p607nTjbd9lga99mWrjpf3Nx9dVmjMSK0pz0JrrxFrcQ0kAgQIECBAgAABAgQIECBAgAABAgQIECBAYMYSqIuAVnnS5o2Y2nqzebLdt95s7gbNDHo9glWRSgNjXQrBrLnSMkt1T8cU/ga9Ni6rceNtnxfWx2br3/zTvON/U98aAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIDAtBCoi4BWPpqn4eis0tMtHbUV+ZO3/3bRoqWViuuNg1vFgkYrEdiKFMGtSHse9G62zNufslFYlD9+Xp73v9wyz4u6+XrpcpZZZkkLLbRQmnvuudPw4cOzvwkTJmRNR728bmTMO++8ab/99svK4p/XX389XXvttWnllVdOG264YTH/7rvvTo8//ni2b+n++XrpMl+PnfP10mW+3hHKiwBWCBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgRlKoC4CWlMjus3mk0dmTc2+lfaJNm+45dNKxVOV36VL05Fe3bp1S1tvvXVae+21U69evVJpnQhmvf/++2ngwIFZUKq0bNZZZ00rrLBCsR9fffVVtm/v3r0b5D/33HPFOqX7FzNLVmb08pJTtUqAAAECBAgQIECAAAECBAgQIECAAAECBAh0UIG6CGiVjgJq6hijoxoGhZYtjKhq7iispu1Vzok2B/77k0YVmh6/YYXJo6jiHCI4VGu51FJLpQMOOCD169evYTNTtmaeeea08MILp8MPPzw9+eST6dJLL02fffZZ1m4+civfcfz48WnixInp66+/zrOyZQS6Ir85/anV345U3gDBBgECBAgQIECAAAECBAgQIECAAAECBAgQIDDDCMxU/2fSMJgV/d16GozOyh2ajvxqevy87uRl+fJyI59iysBjjz22QTArAkaDBw/OglcjR45s0PQqq6ySjjjiiOIIrqhbmiJoFSlf5mV5ECrfLrcs17/Seh29vPRcrBMgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIdW6ADjNBqCByjs+JvWqUIaDUdpVX9aHmgqfEy3yvP33PPPVNMG5injz76KJ188snp2WefzbPSjjvumA488MAUI7UiLbnkkmm99dZLd911V/EZV8XKU1by9vP82M7zIjDVt2/fbGrDueaaK/Xo0SONGTMmG/U1bNiw9Omnnxbrxj4xHWJpH7/88stsBFjXrl1T//790/zzz589u+vDDz/MD5ftH8dZdNFFs+eBffDBB+mdd95J+YiyvC9x7AUWWCBFP+IvAnEx+iz6MGTIkGJgLq+fHyDfbrxsXJ5vWxIgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIzlkBdBLTqjXTbLXq2OKhV6xxWXHHFtPLKKzeodtZZZ6V43lUEkSKAFVMHXn311alPnz5pu+22K9bdeeed04MPPljcbu5KTG943HHHNQhQle4bAaU4fhzz3XffzYoieLbXXnsVq1111VUpglrRhwhI5enVV19Nv/nNb9K4cePSOuusk3bZZZc055xz5sXpjTfeSOeff36KoF2kI488MsWIs0rp448/zoJ2N954YzHAVqmufAIECBAgQIAAAQIECBAgQIAAAQIECBAgQKBzCdRFQCsfedMc+qZTAjZnr5bVWWbJWVsUVGlO/2OkVWmKgNDjjz+eevfunWaZZZZi0ejRo9MVV1yRtt122zTTTJNnhJxtttnSggsumI2sKlacslLu2JEXf9Fu6WirxvtG+9/5znfSgAED0vHHH59iysPG7UU/SgNZeRtLL710Nh1iPMcr2micllhiiSwwdvbZZ2dFMSKrWurVq1faYYcdsuBeBNgkAgQIECBAgAABAgQIECBAgAABAgQIECBAgEAuUBcBrbwztZbLLt0jxV+lFFMFvvLauLRtYdrASvXy6QSzqQsrtJUf55VXx1Y6VIvz+/Xr12Cf1157Lc0zzzwN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VDb1X+moqcJ6MX5Vn+XtOeKpJRdbXQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIBARxSoixFaXWfOI1aFZb6aazbYrvfyvNOW01ugdCrD6X1sxyNAgAABAgQIECBAgAABAgQIECBAgAABAgSmrUBdBLQWXGDWwnOzJpX8FQZqdaDtuET5KC3LyaPrprfDQgstNG1fKVonQIAAAQIECBAgQIAAAQIECBAgQIAAAQIE2k2gLgJa31ttrnYDcOAZQ+D73//+jHEizoIAAQIECBAgQIAAAQIECBAgQIAAAQIECBBoIlAXz9D68Zbzpocf+yy9M3hcoYP587M6znLixIkZbONRSZEZeY3z823lbePTv3//tP3222fXwD8ECBAgQIAAAQIECBAgQIAAAQIECBAgQIDAjCdQFyO0gvWoQxdO/Rfp3qGFu3Rp8MCvJueivO19BgwYkI4++ugm1jIIECBAgAABAgQIECBAgAABAgQIECBAgACBGUegS2G0UD4Uqi7O6rqbPkwPP/5ZGjp0XBo/oS66VLMT4z8/rmYdFdpOYOaZZ04LL7xwWmuttdIOO+zQdg1riQABAgQIECBAgAABAgQIECBAgAABAgQIEKhLgboLaNWlkk4RIECAAAECBAgQIECAAAECBAgQIECAAAECBAi0m0DdTDnYbgIOTIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgUNcCAlp1fXl0jgABAgQIECBAgAABAgQIECBAgAABAgQIECBAQEDLPUCAAAECBAgQIECAAAECBAgQIECAAAECBAgQIFDXAgJadX15dI4AAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQEBAyz1AgAABAgQIECBAgAABAgQIECBAgAABAgQIECBQ1wICWnV9eXSOAAECBAgQIECAAAECBAgQIECAAAECBAgQIEBAQMs9QIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgUNcCAlp1fXl0jgABAgQIECBAgAABAgQIECBAgAABAgQIECBAQEDLPUCAAAECBAgQIECAAAECBAgQIECAAAECBAgQIFDXAgJadX15dI4AAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQEBAyz1AgAABAgQIECBAgAABAgQIECBAgAABAgQIECBQ1wICWnV9eXSOAAECBAgQIECAAAECBAgQIECAAAECBAgQIEBAQMs9QIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgUNcCAlp1fXl0jgABAgQIECBAgAABAgQIECBAgAABAgQIECBAQEDLPUCAAAECBAgQIECAAAECBAgQIECAAAECBAgQIFDXAgJadX15dI4AAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQEBAyz1AgAABAgQIECBAgAABAgQIECBAgAABAgQIECBQ1wICWnV9eXSOAAECBAgQIECAAAECBAgQIECAAAECBAgQIEBAQMs9QIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgUNcCAlp1fXl0jgABAgQIECBAgAABAgQIECBAgAABAgQIECBAQEDLPUCAAAECBAgQIECAAAECBAgQIECAAAECBAgQIFDXAgJadX15dI4AAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQEBAyz1AgAABAgQIECBAgAABAgQIECBAgAABAgQIECBQ1wICWnV9eXSOAAECBAgQIECAAAECBAgQIECAAAECBAgQIEBAQMs9QIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgUNcCAlp1fXl0jgABAgQIECBAgAABAgQIECBAgAABAgQIECBAQEDLPUCAAAECBAgQIECAAAECBAgQIECAAAECBAgQIFDXAgJadX15dI4AAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQEBAyz1AgAABAgQIECBAgAABAgQIECBAgAABAgQIECBQ1wICWnV9eXSOAAECBAgQIECAAAECBAgQIECAAAECBAgQIEBAQMs9QIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgUNcCAlp1fXl0jgABAgQIECBAgAABAgQIECBAgAABAgQIECBAQEDLPUCAAAECBAgQIECAAAECBAgQIECAAAECBAgQIFDXAgJadX15dI4AAQIECBAgQIAAAQIECBAgQIAAAQIECBAgKLa4NwAAQABJREFUQEBAyz1AgAABAgQIECBAgAABAgQIECBAgAABAgQIECBQ1wICWnV9eXSOAAECBAgQIECAAAECBAgQIECAAAECBAgQIEBAQMs9QIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgUNcCAlp1fXl0jgABAgQIECBAgAABAgQIECBAgAABAgQIECBAQEDLPUCAAAECBAgQIECAAAECBAgQIECAAAECBAgQIFDXAgJadX15dI4AAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQEBAyz1AgAABAgQIECBAgAABAgQIECBAgAABAgQIECBQ1wICWnV9eXSOAAECBAgQIECAAAECBAgQIECAAAECBAgQIEBAQMs9QIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgUNcCAlp1fXl0jgABAgQIECBAgAABAgQIECBAgAABAgQIECBAQEDLPUCAAAECBAgQIECAAAECBAgQIECAAAECBAgQIFDXAgJadX15dI4AAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQEBAyz1AgAABAgQIECBAgAABAgQIECBAgAABAgQIECBQ1wICWnV9eXSOAAECBAgQIECAAAECBAgQIECAAAECBAgQIEBAQMs9QIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgUNcCAlp1fXl0jgABAgQIECBAgAABAgQIECBAgAABAgQIECBAQEDLPUCAAAECBAgQIECAAAECBAgQIECAAAECBAgQIFDXAgJadX15dI4AAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQEBAyz1AgAABAgQIECBAgAABAgQIECBAgAABAgQIECBQ1wICWnV9eXSOAAECBAgQIECAAAECBAgQIECAAAECBAgQIEBAQMs9QIBAiwQmTJiQ3nrr7TRp0qQW7deZK48dOy4NHfpeZyZw7gQIECBAgAABAgQIECBAgAABAgQIEGiVQIcIaMUX6O++Ozg9/Mij6brrb0jXXjcw3XPv/WnQoFfTxIkTWwVg584j8O9bbkurrL5W9nfm2ed2nhNvwzMdPmJEWm/9TdKPNtw0+/vss8/bsPUZs6n/PfhQWnWNtdLa66yffnrYEa06ye+ttW52/8Zy1KhRrWqr2s7/uvra4mvlD3+8uFpVZRUEpte1qnB42QTqUmB6fA6/8sqg4vvX3vseUJcOOkWAAAECBAgQIECAAAECBAhMnUDXqdtt+uz1+eej0vUDb0h/vuSvadiwYWUP2rt377T9dtukw356SOrRo3vZOjIJhMDo0aPTyJEjM4yPPpq8JNMygYEDb0qDhwzJdnr77XfSrbfdnnbZeceWNdLJav/5ksvSmDFjsrMOr8MOPTgtteQSU6VQ+j44fvz4qWqjOTtFoDJ/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mLmXLgar0r2UskeLPVcyQ+pmM6a9xjkor7nqslBs/qGCoo26utsee4WXXp4aGE83pNRnSJwX89STT6i3XtfpY1omQIAAAQIECBAgQIAAAQIECBCYcYHmM16FGggQIFC/AnHIqqeffDQzVFhhzYXBrPjQvf9tN+XNHVe4j/VZW8D9MHOv3yEHHRAuvvC8akPtFQtmbbP1luHO/rdWfDArit1w3VUh9rgqTIWfIXH7KScdH87892mCWYVY1gkQIECAAAECBAgQIECAAAECFSSgh1YFXYzpbcp99z8QBr75Vmb3bbfZKqy80orTW5X9CFScwLPPPR8GD34nfPjRsPDhhx+G336bEJZYYvHM0Jo9ey6Vud+7dOlcce3WoJkj4H6YOa6x1m+//S48+vgTYdiwj5P32kfh669HZIYdXH755cKyyywdlkn+VujdKzRrlowJOgulIcnQgs+/8GIYlgw9OGToh+Gbb74N3RdZOMSeZssuu3TotfzyIQ69KBEgQIAAAQIECBAgQIAAAQIECFS2gIBWZV8frSNAgAABAgQIECBAgAABAgQIECBAgAABAgQINHkBQw42+VsAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgsgUEtCr7+mgdAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKDJCwhoNflbAAABAgQIECBAgAABAgQIECBAgAABAgQIECBAoLIFBLQq+/poHQECBAgQIECAAAECBAgQIECAAAECBAgQIECgyQsIaDX5WwAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKCyBQS0Kvv6aB0BAgQIECBAgAABAgQIECBAgAABAgQIECBAoMkLCGg1+VsAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgsgUEtCr7+mgdAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKDJCwhoNflbAAABAgQIECBAgAABAgQIECBAgAABAgQIECBAoLIFBLQq+/poHQECBAgQIECAAAECBAgQIECAAAECBAgQIECgyQsIaDX5WwAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKCyBQS0Kvv6aB0BAgQIECBAgAABAgQIECBAgAABAgQIECBAoMkLCGg1+VsAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgsgUEtCr7+mgdAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKDJCwhoNflbAAABAgQIECBAgAABAgQIECBAgAABAgQIECBAoLIFBLQq+/poHQECBAgQIECAAAECBAgQIECAAAECBAgQIECgyQsIaDX5WwAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKCyBQS0Kvv6aB0BAgQIECBAgAABAgQIECBAgAABAgQIECBAoMkLCGg1+VsAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgsgUEtCr7+mgdAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKDJCwhoNflbAAABAgQIECBAgAABAgQIECBAgAABAgQIECBAoLIFBLQq+/poHQECBAgQIECAAAECBAgQIECAAAECBAgQIECgyQsIaDX5WwAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKCyBQS0Kvv6aB0BAgQIECBAgAABAgQIECBAgAABAgQIECBAoMkLCGg1+VsAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgsgUEtCr7+mgdAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKDJCwhoNflbAAABAgQIECBAgAABAgQIECBAgAABAgQIECBAoLIFBLQq+/poHQECBAgQIECAAAECBAgQIECAAAECBAgQIECgyQsIaDX5WwAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKCyBQS0Kvv6aB0BAgQIECBAgAABAgQIECBAgAABAgQIECBAoMkLCGg1+VsAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgsgUEtCr7+mgdAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKDJCwhoNflbAAABAgQIECBAgAABAgQIECBAgAABAgQIECBAoLIFBLQq+/poHQECBAgQIECAAAECBAgQIECAAAECBAgQIECgyQsIaDX5WwAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKCyBQS0Kvv6aB0BAgQIECBAgAABAgQIECBAgAABAgQIECBAoMkLCGg1+VsAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgsgUEtCr7+mgdAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKDJCwhoNflbAAABAgQIECBAgAABAgQIECBAgAABAgQIECBAoLIFBLQq+/poHQECBAgQIECAAAECBAgQIECAAAECBAgQIECgyQsIaDX5WwAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKCyBQS0Kvv6aB0BAgQIECBAgAABAgQIECBAgAABAgQIECBAoMkLCGg1+VsAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgsgUEtCr7+mgdAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKDJCwhoNflbAAABAgQIECBAgAABAgQIECBAgAABAgQIECBAoLIFBLQq+/poHQECBAgQIECAAAECBAgQIECAAAECBAgQIECgyQsIaDX5WwAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKCyBQS0Kvv6aB0BAgQIECBAgAABAgQIECBAgAABAgQIECBAoMkLCGg1+VsAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgsgUEtCr7+mgdAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKDJCwhoNflbAAABAgQIECBAgAABAgQIECBAgAABAgQIECBAoLIFBLQq+/poHQECBAgQIECAAAECBAgQIECAAAECBAgQIECgyQsIaDX5WwAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKCyBQS0Kvv6aB0BAgQIECBAgAABAgQIECBAgAABAgQIECBAoMkLCGg1+VsAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgsgUEtCr7+mgdAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKDJCwhoNflbAAABAgQIECBAgAABAgQIECBAgAABAgQIECBAoLIFBLQq+/poHQECBAgQIECAAAECBAgQIECAAAECBAgQIECgyQsIaDX5WwAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKCyBQS0Kvv6aB0BAgQIECBAgAABAgQIECBAgAABAgQIECBAoMkLCGg1+VsAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgsgUEtCr7+mgdAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKDJCwhoNflbAAABAgQIECBAgAABAgQIECBAgAABAgQIECBAoLIFWlZ287SuPgWmTJkSfvjhhzBi5KgwZszY0LlTx9C1W9fQYZ55QrNmzerzUJm64jFGjx4dvv/+h/D7lN9Dxw4dQqdOnULHjh1CixYt6v14KiRAgAABAgQIECBAgAABAgQIEFcHOvkAAEAASURBVCBAgAABAgRmTwEBrdnzuubOKgaw7rnvgXDX3feGIUOG5vILF5Zbdpnwxz/uGLbZassw99xzFW4ue/2twW+HRx59PDzw4P+FkSNHFt2vffv2YastNw+bbLxhWG/ddWZKMK3ogWUSIECAAAECBAgQIECAAAECBAgQIECAAAECs6RAs6TXzpRZsuUaXaPA999/H84+9/xw54C7ayxXbOPuu+0Sjj7qiDoFtkaOGhXOOPOc8OBDDxersmTeqquuHE47+cTQs+dSJcvYQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECDRtAQGt2fD6x55Ye+17QMkeUuWcco8e3cO1V10eFl20R63Fhw79MOzwx13DL7/8UmvZUgVuufH60KfPmqU2yydAgAABAgQIECBAgAABAgQIECBAgAABAgSasICA1mx28Z96+tmwz34H1MtZxaEBr7vmirD6aquWrG/4l1+G7Xb4U2aurJKFytxw/z13hl69li+ztGIECBAgQIAAAQIECBAgQIAAAQIECBAgQIBAUxEQ0JqNrvTXX48IfdbdoMYz6tatW+i51JKhS5fO4Ztvvg3vvf9BjcGoGNR6/pknQseOHYvWe+Tfjwn3JnN0FUtx31VXWTkstdQSoWWLluHDj4aFNwe9VfJ4K67QO9w94HZzahXDlEeAAAECBAgQIECAAAECBAgQIECAAAECBJqwgIDWbHLxf//997Dn3vuFF154qegZxWDR3w47OKy7ztp5AaO43/+eejpcfMnl4d333i+67xabbxYuvfj8ats+//yL0LffJtXyY8YeyTxcx/7zH6Fdu7Z52ydNmhSuuPKacP6FF+flZ1cMPZiV8EqAAAECBAgQIECAAAECBAgQIECAAAECBAhkBZpnF2al1wkTJoSxY3+sU5PHjRsX4l99pVjXTz/9FKZMmVJfVWbqGTd+fObc6lrvPffeXzKYteMO24UBd9wa1lt3nbxgVjxg8+bNw0Yb9gt33Xlb2GTjDYuey/89/Eh48n9PVdsWe1sVSwf8dd9w2qknVQtmxbItW7YMhx5yYLjskguK7Rpeff31ovkyCRAgQIAAAQIECBAgQIAAAQIECBAgQIAAgaYr0LJSTj0GcI497sQwYeLEvCbtucduoXfvXuHLL78KN918a7gnGd5u9OjRmTKdO3cOvXstF3bYftuw+Wab5u0XVx597Ilw3/0PhMFvvxtGjhyZ2R6HwVt9tVXCn3beKRPIqbZTkYzYq+jxJ54MQ4Z+GIYM+TC88+57ufpi8TiMX9/11gkb9dsgrJe8tmjRokgtxbM+/PCjMOCue8ILL70chg//Mvzyyy+5grHeNddYLWyZ9JBaZ50+oVWrVrlthQs333p7YVZmPbqcfea/MoGrogWmZbZp0yYJMl0Y/rLP/kUDY7f3vzNsmJxfOn32+efp1dzylltsnlsutbDJxhuFhRdaKHwxfHhekcGD38lbt0KAAAECBAgQIECAAAECBAgQIECAAAECBAgQqJghB+PQd4stuWy1K3LBeeeEebt0CbvvuXe1bemMrbbcPJz579NCDFjF4NWxx58cnnn2uXSRastHHfm3cMhBB1TLT2cM+/jjcMSR/yg5HF+6bFzu1Wv5cPYZp4eePZcq3JS3HuevOuof/ywaPMorOG1licUXC+eefUYmuFe4PQaF1lt/48LszPrLLz4TunXtWnRbscxPPvk09Nu4eEBq0BuvhA4d5sntdsJJp4Zbb+ufW88uPPO/x8IiiyycXS35OuitwWFoEiRMp4UWXDD06bNmOssyAQIECBAgQIAAAQIECBAgQIAAAQIECBAg0MQFKn7IwU8/+6zWYFa8hg8+9HC46OLLQuxN9deDDqs1mBX3Oe/8i8I1114fF4umm265LWy0yZZlB7NiJW+//U7YcefdQgyElUpvDX47bL7VdmUHs2I9Hw37OGy7w87hqaeeqVbtY0lPtGLpsEMPqlMwK9ax6KI9MvNfFauvcNjBGGgslu657/5i2dXy4rxesadc+k8wqxqTDAIECBAgQIAAAQIECBAgQIAAAQIECBAg0OQFKj6gdfEll5d9ka657oZweNKbKgaVyk1nnHVueGPgm9WKP//Ci+HkU06vll9ORhw2cP8DDgmx11lhisMl7v7nvXPDJhZur219n/0PDO+9/0FesRdefDlvPbsS58aanhSHAyyWXnr5lbzshRZaMG89uxKv2cmn/ivE+cAkAgQIECBAgAABAgQIECBAgAABAgQIECBAgMCMClTMHFrlnEjs0RN7EL056K3w6aefFd3l/x5+JC8/BnXatm0TXn/jzbx5r9KF7rv/wbDKyiuls0IMdBVLcei/Pn3WyszdNWnS5BCDPPcm83oVpti+555/IZlba928TcefeErePFnpjeuus3ZYb911Qps2rTPnd90NN6Y355bPOff8cOMN1+TWR4wYkVvOLsT5xZZZumd2tU6vq6ySb5HdedSob7KLmdf1118vbz29Euc7i39xDq9NN9korJrUGecEkwgQIECAAAECBAgQIECAAAECBAgQIECAAAECdRWYJQJaMThz7939Q5xfKZtuu/2OEINDpdIWm28WLjz/nNCyZdUpxl5DMchSmF577fW8rFHffBOGDBmalxdXNtl4w3D5pReF5s2rOrbtuMN2YbNNN870yCrc4eVXXssLaL3z7nvhscefLCyWWT//P2eH7bbdOm/bgQfsFw5Ihk8s7EEWA2Wxfdl5ur4eMTJvv7iy/HLL5rWzWoEaMtq0aROWW3aZakMtjkjmJkunjh06hH322jOUCrzFsg8/8mjmLy7H67j6aquGlVdaMaydzJO1xBKLh2bNmsVNEgECBAgQIECAAAECBAgQIECAAAECBAgQIECgpEBVtKdkkcbfcNvNN+QFs2KLdt1l5xADRP3vGFCtgbG31QXnnZ0XzIqFTjrh2PDa629UC1YVBoSmJEMF7rD9tnn1tm3bNhx7zN+LBoliL7B4zMLA0/Dhw/PqePTRx/PWsytxDqnCYFbcFgNAV1x2cejbb5NqvbpeT4ZJjAGt8eN/rbYt7tulS+f4Mt2pS5H5sYr1ivvH0UdmeswNemtwrceKwy0WBrj2+sseYZfk/Dt16lTr/goQIECAAAECBAgQIECAAAECBAgQIECAAAECTVOgqqtRhZ5/HIZvySWXKNq6tdZco2j+lltsFlq1alVtW4sWLcJqq65SLT/OeZVOcWi8/5xzZt7fv047ObRv3z5dLG956SS4VJjGjv0xL+ueIkMTxqDVSSccl1cuvRIDU8WCXcO/mBosGzt2TLp4bjn2npqR1LFj8f1//fXXvGpbt24dbr35v2HnnXbIyy9nJQa4/nPehWHl1fqEu+6+t5xdlCFAgAABAgQIECBAgAABAgQIECBAgAABAgSaoEDF99CKcy+VSnE+rWKpd+9exbIzeUsmw9zVZxo3fnz4+aefw8effFpjtbEn1ciCIfviDmutuXpo165tjfuefupJIf4VS+3azVEsO8R2zUgaN25c0d1jAKswxfafdea/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BOomIKBVNy+lCRAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEGlhAQKuBwR2OAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgbgICWnXzUpoAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKCBBQS0Ghjc4QgQIECAAAECBAgQIECAAAECBAgQIECAAAECBOomIKBVNy+lCRAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEGlhAQKuBwR2OAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgbgICWnXzUpoAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKCBBQS0Ghjc4QgQIECAAAECBAgQIECAAAECBAgQIECAAAECBOomIKBVNy+lCRAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEGlhAQKuBwR2OAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgbgICWnXzUpoAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKCBBQS0Ghjc4QgQIECAAAECBAgQIECAAAECBAgQIECAAAECBOomIKBVNy+lCRAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEGlhAQKuBwR2OAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgbgICWnXzUpoAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKCBBQS0Ghjc4QgQIECAAAECBAgQIECAAAECBAgQIECAAAECBOomIKBVNy+lCRAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEGlhAQKuBwR2OAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgbgICWnXzUpoAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKCBBQS0Ghjc4QgQIECAAAECBAgQIECAAAECBAgQIECAAAECBOomIKBVNy+lCRAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEGlhAQKuBwR2OAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgbgICWnXzUpoAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKCBBQS0Ghjc4QgQIECAAAECBAgQIECAAAECBAgQIECAAAECBOomIKBVNy+lCRAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEGlhAQKuBwR2OAAECBAgQIECA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sICA1ix88TSdAAECBAgQIECAAAECBAgQIECAAAECBAgQINAUBFpWwkn2PuDdSmiGNsyiApccvEhYd/m5ZtHWazYBAgQIECBAgAABAgQIECBAgAABAgQIECBQm4AeWrUJ2U6AAAECBAgQIECAAAECBAgQIECAAAECBAgQINCoAgJajcrv4AQIECBAgAABAgQIECBAgAABAgQIECBAgAABArUJNJuSpNoK2U6AAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgsQT00GosecclQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAoS0BAqywmhQgQIECAAAECBAgQIECAAAECBAgQIECAAAECBBpLQECrseQdlwABAgQIECBAgAABAgQIECBAgAABAgQIECBAoCwBAa2ymBQiQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBBoLAEBrcaSd1wCBAgQIECAAAECBAgQIECAAAECBAgQIECAAIGyBAS0ymJSiAABAgQIECBAgAABAgQIECBAgAABAgQIECBAoLEEBLQaS95xCRAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEyhIQ0CqLSSECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIHGEhDQaix5xyVAgAABAgQIECBAgAABAgQIECBAgAABAgQIEChLQECrLCaFCBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEGktAQKux5B2XAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgLAEBrbKYFCJAgAABAgQIECBAgAABAgQIECBAgAABAgQIEGgsAQGtxpJ3XAIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgbIEBLTKYlKIAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgsQQEtBpL3nEJECBAgAABAgQIECBAgAABAgQIECBAgAABAgTKEhDQKotJIQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgcYSENBqLHnHJUCAAAECBAgQIECAAAECBAgQIECAAAECBAgQKEtAQKssJoUIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQaS0BAq7HkHZcAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKAsAQGtspgUIkCAAAECBAgQIECAAAECBAgQIECAAAECBAgQaCwBAa3GkndcAgQIECBAgAABAgQIECBAgAABAgQIECBAgACBsgQEtMpiUogAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKCxBAS0GkvecQkQIECAAAECBAgQIECAAAECBAgQIECAAAECBMoSENAqi0khAgQIECBAgAABAgQIECBAgAABAgQIECBAgACBxhIQ0GosecclQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAoS0BAqywmhQgQIECAAAECBAgQIECAAAECBAgQIECAAAECBBpLQECrseQdlwABAgQIECBAgAABAgQIECBAgAABAgQIECBAoCwBAa2ymBQiQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBBoLAEBrcaSd1wCBAgQIECAAAECBAgQIECAAAECBAgQIECAAIGyBAS0ymJSiAABAgQIECBAgAABAgQIECBAgAABAgQIECBAoLEEBLQaS95xCRAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEyhIQ0CqLSSECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIHGEhDQaix5xyVAgAABAgQIECBAgAABAgQIECBAgAABAgQIEChLQECrLCaFCBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEGktAQKux5B2XAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgLAEBrbKYFCJAgAABAgQIECBAgAABAgQIECBAgAABAgQIEGgsAQGtxpJ3XAIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgbIEBLTKYlKIAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgsQQEtBpL3nEJECBAgAABAgQIECBAgAABAgQIECBAgAABAgTKEhDQKotJIQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgcYSENBqLHnHJUCAAAECBAgQIECAAAECBAgQIECAAAECBAgQKEtAQKssJoUIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQaS0BAq7HkHZcAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKAsAQGtspgUIkCAAAECBAgQIECAAAECBAgQIECAAAECBAgQaCwBAa3GkndcAgQIECBAgAABAgQIECBAgAABAgQIECBAgACBsgQEtMpiUogAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKCxBAS0GkvecQkQIECAAAECBAgQIECAAAECBAgQIECAAAECBMoSENAqi0khAgQIECBAgAABAgQIECBAgAABAgQIECBAgACBxhIQ0GosecclQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAoS0BAqywmhQgQIECAAAECBAgQIECAAAECBAgQIECAAAECBBpLQECrseQdlwABAgQIECBAgAABAgQIECBAgAABAgQIECBAoCwBAa2ymBQiQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBBoLAEBrcaSd1wCBAgQIECAAAECBAgQIECAAAECBAgQIECAAIGyBAS0ymJSiAABAgQIECBAgAABAgQIECBAgAABAgQIECBAoLEEBLQaS95xCRAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEyhIQ0CqLSSECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIHGEhDQaix5xyVAgAABAgQIECBAgAABAgQIECBAgAABAgQIEChLQECrLCaFCBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEGktAQKux5B2XAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgLIGWZZVSKLz++sBw+x13htGjvw+9ey8f9ttnrzDXXHORIUBgJgmMGz8+XHfdf8Obg94K88wzd9hh+23DOmv3mUlHUy0BAgQIECBAgAABAgQIECBAgAABAgQIVLJAsylJquQGVkLbXnzx5bD7nnvnNWW5ZZcJ9959R2jZsrJjgkOHfhjOOOvcvLa3bNkiXHLR+WGOOebIy7dCoFIEJk+eHHbZfc9MIDndpquuuDRsvFG/dJZlAgQIECBAgAABAgQIECBAgAABAgQIEGgCAhURjRk79sdw5lnnVONeZZWVw447bFctvzBj4JuDwoABd+dlL7zIwuGgA/bPyyu28tVXX4dLLr282qZ+/dYPG2049cH5DTfeXG37u++9H+JxV19t1WrbKinju+9Gh+eef6Fak8YnvV8EtKqxyKgQgfff/6BaMCs27Yb/3iSgVSHXSDMIECBAgAABAgQIECBAgAABAgQIECDQkAIVEdBq1bpVuKMgIBUR3kseapcT0HrwoYeL7r/v3n8JrVu3rtHz9TfeKLrvCiv0zu03atSo3HJ6YfTo0elVywQI1JPA6O+/L1rTqG++KZovkwABAgQIECBAgAABAgQIECBAgAABAgRmb4HmlXB6c7RrF9Zac41qTYm9oMaNG1ctvzDj6aefLczKrA8e/E7R/HTmGwMHpVdzy2usvlpueaWVVswtpxd6LrVUetUyAQL1JLDUkksWrWmF3r2K5sskQIAAAQIECBAgQIAAAQIECBAgQIAAgdlboCICWpF4vXXXLir99jvvFs3PZo4YMTJ8MXx4djXv9eVXXs1bL7by0suvVMvu1q1b6N59kVz+YYccGJZYfLHcelw45uijwqKL9sjLs0KAQP0IzD9/t3DaqSflVbbwQguFo486Ii/PCgECBAgQIECAAAECBAgQIECAAAECBAg0DYGKGHIwUq+5xupFxQcNGhzSvaUKC7362muFWbn1Z559Lhx26EG59cKFMWPGhk8//awwO/TboG9eXufOncNDD9yTmTNrwoQJYZGFF84LeOUVtkKAQL0I7LHbLplA9+effxGaN28RVlpxhdCuXdt6qVslBAgQIECAAAECBAgQIECAAAECBAgQIDBrCVRMQGuZZZYO7du3D7/88kue4BsDBybr++XlpVdefKl6D6vs9kFvDQ4//vhTmHvuubJZea/vvFu891eftaoPfxjn4ioVdMur1AoBAvUmEHtlxT+JAAECBAgQIECAAAECBAgQIECAAAECBJq2QMUMOdiiRYvQd711q12NV197I0yePLlafsyYMmVKePqZ54puy2a+MfDN7GK119j7q1hafbVVi2XXa14MtP3666/1Uufvv/9e0qheDjCtkp9++qlawLE+62/IuuK9E89n7NgfQ/RrzDRp0qSZcvh4jhMnTqxT3ePH/5oxqdNOFV44Xudx48dXeCs1jwABAgQIECBAgAABAgQIECBAgAABAgRqEqiYHlqxkeus0yf838OP5LU39tj6+JNPw5JLLJ6XH1c+/uSTMHr06Gr56YyXXno5bLD+eums3PKrr72eW84uLLfsMqFTp07Z1czrG28MDLf1vzMvb86kN1nhHD/XXv/f8P77H+SVW7vPWmH77bYJv/32W3jwoYfDbbffEWLPsWyKvU+WXXbpsPFG/cI2W28VmjVrlt1U4+vrrw8Mt97eP3O8j4Z9nCnbo0f30Gv55cKmm2yc/G1U4/7lbBz45qAwYMDd4c1Bb4XsMeJ+sSfdQgstGFZdeaWw0047hOWXW7ZodWefe14YNeqbvG3r910vbLXl5nl52ZWvvvo6nHfBRdnV3OuJJxwbOnbokFtPLwy4655QOFfassk13GevPdPFMstxvrTHHn8yPJMEQQvnXYvDSq7fd93kXumbuRYxwDq9KQ51+cCD/5e3e9eu82XmXYuZP/zwQ7ju+hvD4HfeCTGoGu/xaLp0z6XCOmv3CXvsvkvo2LFj3v7plZrqj3XdfseAcPc994UhQ4bmdrvhuquKBozj+2fAXfeGx594Mnz40bC8gGWcN27l5BrvsvNOoVev5XN1ZRdioPn4E04OEwqCZkssvng48IDSvSqz+5908mnh54IemUsv3TPst89emSKn//vMxGpMtnjmdacdt6+1p2S8V+P77JVXX8sziMY9krnx+vVbP/xxxx3CAgvMn1d3dqXS7ttsu7wSIECAAAECBAgQIECAAAECBAgQIECgKQtUVEBrjRI9o95KAkDFAlqvvlo9IFV4MZ965tlwwvH/LMwOsVdMDHAUpnXXWbswKxPMufe+B6rlFwa0nn3u+fDCCy/llWvTpk0SqNoyHPq3o8ITT/4/e/cBLkV16AH8SAcVERSw0ey9xgIWxN57Nxp7j70ksfcSNbaoyTOJXdOssbfYY6+JDbCAAoqgoiJS3pzF3bs7O3vvgsgd4He+72ZnzpyZOfObvTy/+3/nnIcrjsWdGKzEn3vve6AQeJ191umhW9euVe2KFTGAOOjQw0MMtNIlrgcWf+648+7Qd43Vw9lnnpZuUtd+DAR+ecTRFWFA+YkxNIlhSfy5/sabw4orLB9+d/EFVVPDvfXWOyGGL+Vl5MjPawZaTyXhY5ZzDOhi4JdVbk6CxvKAMLaZc87KKSbjqKMYjsS2tUp0/fs/biv8xCDnnLPPCCuvtGKt5o3W//d/b1U9R/fu3QuB1q1//XvSl3MrgqN4sWgaRxPGn4svuSycevJvwp577J55n1rXj0HQzrvuURE+Fi/wzTffFDcLnzGMiuHhlVf9saK+fCd+D+LPLUlAtkoSbF12yYUhPkexxNDv1dffyPye7L3XHiF+92uVQUlIHb876RKDv2K59a//qHJaYfnlagZao0aPDsce9+vw8COPFi9R8RmN33jzv4WfSy69Iuy2687hpN+cUNXPvHxvKzpvhwABAgQIECBAgAABAgQIECBAgAABArO4QG6mHIzvoWfPHhV/MC++m5eSkUJZ5Yknn6qqLv+DezwYA55hw4dXtXv7nXer6mJF375rZNZPbeWkZDq7c869IDPMSl/zkUf/HX6x9/41pw/85JNhYYedd88Ms9LXimHdHr/YN3z51ZfpQ43uxxFMG268eWZIUevEGChtuvk24amnnqloEkcbpcvjTzxZ8/meefa5dPPCfnoEVrFRnLIxHWbFY2v2a3iHAwcOCltts32jYVbxesXPGOJsv+OuVc9TPD61n/fed3844dcnVYU0Wdc79fSzksDp0qxDNeuOO+HEzDArfUKcgm//Aw9pNMxKnxODts0KAL6pAABAAElEQVS32j68+uprFYd22G7biv3izgsv1J7qM7Z58qnK4Ld43uabZY/eKx6v9Rnf89bb7FgzzMo678abbgm77LZn+OyzylGeefjeZvVXHQECBAgQIECAAAECBAgQIECAAAECBGZlgVwFWvFFrJ9MB5YuWUFHHGHyZCpA6d27Vzhw/33Sp4fnknW40iWO+soqK624Qlb1VNfdmkzZd82fr637/DjqKWuUUlwP6ahjji8EdPVeLI78Ovb439TbvDBy5cCDD6u7fXnDOPpl9z33Du+//0Gpuu8aq5W2yzcGJSFjusTnyxrBFtvFkW9Z5a2338mqDqv+bPIaaPE7sve+B9YV8mRd6IDEIq6xNS3KsGHDwsGHHjFFl7r8iiuTqQCrR/VlXSRev9bIpHT7E359cojh6ZSWOIpttz32LkyZWDx30002LG5WfD6ajIxsrDz48CNVh3v37hWWXmrJqvqmKiZ/9/apmkayqfPi8RiIHnnMcRXrqDX397aefmtDgAABAgQIECBAgAABAgQIECBAgACBWU0gd4FWnCovXWIwkx5F8WYydVj8Q3Z5idPS9SsbnVM8FqeyS5e4PlS6rLlm39C+fbt09TTd32D99cJOybpTca2uWuXc8y8MMeApL/+6577CmkDldeXbcY2j7bbdOsTrl5e0Ufmx8u04LV+cZrBW2WbrLQtrhp126klh0002rtWsELrFICmWxRZbtLA2VLpxepRPPP5eMsKmVl/jKLvhI0akLxNee+31qro4/eFcc3Us1N//wIOZIUdct+yaP1wZnn7i0XD/vXcVnitOqZcusT+NTVOYbj8l+7179wpbb7VlwTKu31WrnHLamSG+m6kp8bpx+sRYWrVqXfi85977QvzJKnG6zTg95yUX/zbsvtsuIatf0eSkU84onR5HRGb9zj74UHVgVTwpjhBLT80Zj22/3TbFJlP0eV7y+xIDvXSJa2bF9drOO+fMcG4yheRmm26S+X2MfSl/z839vU0/h30CBAgQIECAAAECBAgQIECAAAECBAgQSP7OnTeE1VZdJbNLMbwYMKB/6diz/6menm6tfv3CIgsvXJi2sPwP3A8/8lghIJptttlK52eN+lo7Y4q80gk/cuOYo49IRo/tG+K6Q8USR2LFUVfpEkfCxABv3nnnKR264sqrS9vlG/GP9tdfe01hHatifRxVdMppZxTW0irWNfV5x5131Rz9dfed/6wYObPH7rsm4douhena0teNI15imLHxRhuEFi1ahE023rCwLlV5u1eSaevS4cXzz1ePois/58Vkyrt0kPbSy6+UNyls919n7VLdq6+9UdoubkSvf931zzDHHHMUquZL/jeuz7bNVluEDTbeoioYidMdHnjAvsXTp8nnVb+/rLAmWPH7+N1334XLf391iCOy0iV+j/91z71VXul2xf34fOck67D9bJWVStN3xoAxfu/i58mnnllsWvF55RWXFt5ZsXLLLTYLxx1zZNhuh12qRrjF/hz+y0NKYVkMO9Pr0cUQ+r2BAwu/j8VrFj+zfvfisc02rR2UFs9Nf9Zai6vwnpPvbZzGtFh22nH78L9kfbNNt6gOzi6+5PKw8047FJya+3tb7K9PAgQIECBAgAABAgQIECBAgAABAgQIEGgQyN0Irc6dO2eOXkqPqHoiYw2elVdesfBkcaRWeYkB0cBBg0pVMSQoD7yKB1ZfPXuKvOLxqf3ce689wiEHHVARZsVrxSDg58lImKwyZOjQUnVcOytORZhVLr/0ooowK7aJI5TOOeuMsMQSi2edkln3z9vvyKw/NxndkjUN3OqrrRqOPzZ7RNddd99Tula/jDXJnnvu+dLx4sbTz/ynuJn5mRWCpKecjCf27bt66fwhQxoMi5VLJibFMKtYFz9j3VVXXBL22WvPip8B665T3uxHb59+2slhow3XD8UwK16wbdu24agjDivUZ93goYzp+bLaxRDn1puvL4xKKl9LrhiixrAx/i6ky6+OP6YizCoen3POOcM1/3dV5qime++9v9isalRg8cDjj1evcRePZU1HGEfW9ezRED4Vr9HU533JKLys8pdrrq4I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vn3XSFcV9vuvs3ZmfayMYUN8pqzSL/ForHTo0CH84arLC0FgHBXUu3evxpoXAqcbrv1T+L8//H6ahlnxpvGdxuv+8eoravajd+9eIQaRMbiMa15llazvVK1Ralnnx7peybpg/7rztnDhBedm/n6VnxfDtRuu+3OhT3FqynpKnHZywLrrZDbdYbttM+vTlVmjJ2v9XsRz4/0eefDecNwxRxWmk0xfr3x/i803DQ8/cE848/RTao7wK28/vb+35fe2TYAAAQIECBAgQIAAAQIECBAgQIAAAQJJfjEpKSBmTIHvvvsuDB36cRj68ceF9YjmmWee0CtZvygr8JjaJ4z3GDJkaBg+YkT44osvwoQJEwtrZHWdd97Qo8dCTY5smdr7/pTnjR07Nrz//gfh/Q8+DBMnTkimnWwfunSeOyy++GLTZArK31/1h3DBby+ueIQ4Vd8zTz5aUffFF1+GQYMHhzFjxoQYvMWp7aJrHCk3vUt8v598MixZW2t4mDRpYug4Z8ewUI8FwwLzzz9N1rqa3s8zYcKEMGTo0DBi+Kdh2PDhhd+JLl06J2umLVgwbmrtvendX/cjQIAAAQIECBAgQIAAAQIECBAgQIAAgcYFBFqN+zhKYIoF6g20pvjCTiBAgAABAgQIECBAgAABAgQIECBAgAABArOowPQfCjKLQntsAgQIECBAgAABAgQIECBAgAABAgQIECBAgACBqRMQaE2dm7MIECBAgAABAgQIECBAgAABAgQIECBAgAABAgSmk4BAazpBuw0BAgQIECBAgAABAgQIECBAgAABAgQIECBAgMDUCQi0ps7NWQQIECBAgAABAgQIECBAgAABAgQIECBAgAABAtNJQKA1naDdZtYRaN2qVdXDtmnduqpOBQECBAgQIECAAAECBAgQIECAAAECBAgQIFCfwGyTklJfU60IEKhHYOLEiWH8+PEVTVu0aBFaZQRdFY3sECBAgAABAgQIECBAgAABAgQIECBAgAABApkCAq1MFpUECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQJ5ETDlYF7ehH4QIECAAAECBAgQIECAAAECBAgQIECAAAECBAhkCgi0MllUEiBAgAABAgQIECBAgAABAgQIECBAgAABAgQI5EVAoJWXN6EfBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECmQICrUwWlQQIECBAgAABAgQIECBAgAABAgQIECBAgAABAnkREGjl5U3oBwECBAgQIECAAAECBAgQIECAAAECBAgQIECAQKaAQCuTRSUBAgQIECBAgAABAgQIECBAgAABAgQIECBAgEBeBARaeXkT+kGAAAECBAgQIECAAAECBAgQIECAAAECBAgQIJApINDKZFFJgAABAgQIECBAgAABAgQIECBAgAABAgQIECCQFwGBVl7ehH4QIECAAAECBAgQIECAAAECBAgQIECAAAECBAhkCgi0MllUEiBAgAABAgQIECBAgAABAgQIECBAgAABAgQI5EVAoJWXN6EfBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECmQICrUwWlQQIECBAgAABAgQIECBAgAABAgQIECBAgAABAnkREGjl5U3oBwECBAgQIECAAAECBAgQIECAAAECBAgQIECAQKaAQCuTRSUBAgQIECBAgAABAgQIECBAgAABAgQIECBAgEBeBARaeXkT+kGAAAECBAgQIECAAAECBAgQIECAAAECBAgQIJApINDKZFFJgAABAgQIECBAgAABAgQIECBAgAABAgQIECCQFwGBVl7ehH4QIECAAAECBAgQIECAAAECBAgQIECAAAECBAhkCgi0MllUEiBAgAABAgQIECBAgAABAgQIECBAgAABAgQI5EVAoJWXN6EfBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECmQICrUwWlQQIECBAgAABAgQIECBAgAABAgQIECBAgAABAnkREGjl5U3oBwECBAgQIECAAAECBAgQIECAAAECBAgQIECAQKaAQCuTRSUBAgQIECBAgAABAgQIECBAgAABAgQIECBAgEBeBARaeXkT+kGAAAECBAgQIECAAAECBAgQIECAAAECBAgQIJApINDKZFFJgAABAgQIECBAgAABAgQIECBAgAABAgQIECCQFwGBVl7ehH4QIECAAAECBAgQIECAAAECBAgQIECAAAECBAhkCgi0MllUEiBAgAABAgQIECBAgAABAgQIECBAgAABAgQI5EVAoJWXN6EfBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECmQICrUwWlQQIECBAgAABAgQIECBAgAABAgQIECBAgAABAnkREGjl5U3oBwECBAgQIECAAAECBAgQIECAAAECBAgQIECAQKaAQCuTRSUBAgQIECBAgAABAgQIECBAgAABAgQIECBAgEBeBARaeXkT+kGAAAECBAgQIECAAAECBAgQIECAAAECBAgQIJApINDKZFFJgAABAgQIECBAgAABAgQIECBAgAABAgQIECCQFwGBVl7ehH4QIECAAAECBAgQIECAAAECBAgQIECAAAECBAhkCgi0MllUEiBAgAABAgQIECBAgAABAgQIECBAgAABAgQI5EVAoJWXN6EfBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECmQICrUwWlQQIECBAgAABAgQIECBAgAABAgQIECBAgAABAnkREGjl5U3oBwECBAgQIECAAAECBAgQIECAAAECBAgQIECAQKaAQCuTRSUBAgQIECBAgAABAgQIECBAgAABAgQIECBAgEBeBARaeXkT+kGAAAECBAgQIECAAAECBAgQIECAAAECBAgQIJApINDKZFFJgAABAgQIECBAgAABAgQIECBAgAABAgQIECCQFwGBVl7ehH4QIECAAAECBAgQIECAAAECBAgQIECAAAECBAhkCgi0MllUEiBAgAABAgQIECBAgAABAgQIECBAgAABAgQI5EVAoJWXN6EfBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECmQICrUwWlQQIECBAgAABAgQIECBAgAABAgQIECBAgAABAnkREGjl5U3oBwECBAgQIECAAAECBAgQIECAAAECBAgQIECAQKZAq8xalTO0wGuDvwn7XjS48Ay9u7cNt/5mkRn6eco7v+Gv3g6jx4wvVN1+6qJh/i5tyg/bJkCAAAECBAgQIECAAAECBAgQIECAAAECBGZCgVwFWr/757Bw06MjG2XuPGer0LVT69Cja5uw2aqdwupLzhFmm63RU2a5g2PHTQrffT+p8NwjRk8Of2YWhM++GB8mTJz8bGN/eMaZ5dk8BwECBAgQIECAAAECBAgQIECAAAECBAgQIJAtkKtA68tvJpSCmOzuhvDJ598Xfl4d9E2469nRYY72LcMvt+4Wdlqnc61T1BMgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECMzAAjP8Glpjvp0Qzr7543DkVR+GseMmzsCvQtcJECBAgAABAgQIECBAgAABAgQIECBAgAABAgSyBHI1Qqu8g+uv2DFceECP8qrwzXcTw7BR34e3Pvy2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AAECBAgQIECAAAECBAgQIECAAAECBAgQaFYBgVaz8rs5AQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIBAUwKzTUpKU40cJ0CAAAECBAgQIECAAAECBAgQIECAAAECBAgQINBcAkZoNZe8+xIgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECNQlINCqi0kjAgQIECBAgAABAgQIECBAgAABAgQIECBAgACB5hIQaDWXvPsSIECAAAECBAgQIECAAAECBAgQIECAAAECBAjUJSDQqotJIwIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgeYSEGg1l7z7EiBAgAABAgQIECBAgAABAgQIECBAgAABAgQI1CUg0KqLSSMCBAgQIECAAAECBAgQIECAAAECBAgQIECAAIHmEhBoNZe8+xIgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECNQlINCqi0kjAgQIECBAgAABAgQIECBAgAABAgQIECBAgACB5hIQaDWXvPsSIECAAAECBAgQIECAAAECBAgQIECAAAECBAjUJSDQqotJIwIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgeYSEGg1l7z7EiBAgAABAgQIECBAgAABAgQIECBAgAABAgQI1CUg0KqLSSMCBAgQIECAAAECBAgQIECAAAECBAgQIECAAIHmEhBoNZe8+xIgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECNQlINCqi0kjAgQIECBAgAABAgQIECBAgAABAgQIECBAgACB5hIQaDWXvPsSIECAAAECBAgQIECAAAECBAgQIECAAAECBAjUJSDQqotJIwIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgeYSEGg1l7z7EiBAgAABAgQIECBAgAABAgQIECBAgAABAgQI1CUg0KqLSSMCBAgQIECAAAECBAgQIECAAAECBAgQIECAAIHmEhBoNZe8+xIgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECNQlINCqi0kjAgQIECBAgAABAgQIECBAgAABAgQIECBAgACB5hIQaDWXvPsSIECAAAECBAgQIECAAAECBAgQIECAAAECBAjUJSDQqotJIwIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgeYSEGg1l7z7EiBAgAABAgQIECBAgAABAgQIECBAgAABAgQI1CUg0KqLSSMCBAgQIECAAAECBAgQIECAAAECBAgQIECAAIHmEhBoNZe8+xIgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECNQlINCqi0kjAgQIECBAgAABAgQIECBAgAABAgQIECBAgACB5hIQaDWXvPsSIECAAAECBAgQIECAAAECBAgQIECAAAECBAjUJSDQqotJIwIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgeYSEGg1l7z7EiBAgAABAgQIECBAgAABAgQIECBAgAABAgQI1CUg0KqLSSMCBAgQIECAAAECBAgQIECAAAECBAgQIECAAIHmEhBoNZe8+xIgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECNQlINCqi0kjAgQIECBAgAABAgQIECBAgAABAgQIECBAgACB5hIQaDWXvPsSIECAAAECBAgQIECAAAECBAgQIECAAAECBAjUJSDQqotJIwIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgeYSEGg1l7z7EiBAgAABAgQIECBAgAABAgQIECBAgAABAgQI1CUg0KqLSSMCBAgQIECAAAECBAgQIECAAAECBAgQIECAAIHmEhBoNZe8+xIgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECNQlINCqi0kjAgQIECBAgAABAgQIECBAgAABAgQIECBAgACB5hIQaDWXvPsSIECAAAECBAgQIECAAAECBAgQIECAAAECBAjUJSDQqotJIwIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgeYSEGg1l7z7EiBAgAABAgQIECBAgAABAgQIECBAgAABAgQI1CUg0KqLSSMCBAgQIECAAAECBAgQIECAAAECBAgQIECAAIHmEhBoNZe8+xIgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECNQlINCqi0kjAgQIECBAgAABAgQIECBAgAABAgQIECBAgACB5hIQaDWXvPsSIECAAAECBAgQIECAAAECBAgQIECAAAECBAjUJSDQqotJIwIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgeYSEGg1l7z7EiBAgAABAgQIECBAgAABAgQIECBAgAABAgQI1CUg0KqLSSMCBAgQIECAAAECBAgQIECAAAECBAgQIECAAIHmEhBoNZe8+xIgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECNQlINCqi0kjAgQIECBAgAABAgQIECBAgAABAgQIECBAgACB5hIQaDWXvPsSIECAAAECBAgQIECAAAECBAgQIECAAAECBAjUJSDQqotJIwIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgeYSEGg1l7z7EiBAgAABAgQIECBAgAABAgQIECBAgAABAgQI1CUg0KqLSSMCBAgQIECAAAECBAgQIECAAAECBAgQIECAAIHmEhBoNZe8+xIgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECNQlINCqi0kjAgQIECBAgAABAgQIECBAgAABAgQIECBAgACB5hIQaDWXvPsSIECAAAECBAgQIECAAAECBAgQIECAAAECBAjUJSDQqotJIwIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgeYSEGg1l7z7EiBAgAABAgQIECBAgAABAgQIECBAgAABAgQI1CXQqq5WM3ijb779NlxzzV/CSy+/Euaaq2PYbtutw1pr9pvBn0r3CRAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQKzhsBsk5IyMz/qhAkTwi677xmef/7Fise8+srLw4YbrFdRZ4cAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQCB/ArkaofXU08+Gu+66u0KpRcuW4dSTfxPatGlTUV/vzn//+7+qMCue++e/XCfQqhdROwIECBAgQIAAAQIECBAgQIAAAQIECBAgQIBAMwrkKtB68803w61/+0cVx/HHHj3VgdbIzz+vul6sGD5iRGa9SgIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgXwJtMhXd6Z9bxZfbLHMi66w/HKZ9SoJECBAgAABAgQIECBAgAABAgQIECBAgAABAgTyJTDTB1rzzdc9nH7ayRXqPRZaKBx79JEVdXYIECBAgAABAgQIECBAgAABAgQIECBAgAABAgTyKZCrKQd/KqKf77ZLWGftNcMHH3wYWrRoGVZacYXQvn27n+p2rkuAAAECBAgQIECAAAECBAgQIECAAAECBAgQIDANBWaJQCt6xVFZ8UchQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBCYsQRm+ikHf4rXMX78+DB69Bc/xaVdkwABAgQIECBAgAABAgQIECBAgAABAgQIECBAICUwS4zQOuOsc8Ko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U6e5wom/Pj786jcnV9wqTmt43gUXhrPPPK2i3g4BAgQIECBAgAABAgQIECBAgAABAgQIECBAIC8CphycTm/iqCMOm6I7xbWvBqy7TpPnPP/8i+G662+sarfHz3cLSyyxeEX9DttvW1UXG9x8y1/Ds/95rqKtHQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIBAXgQEWtPpTfTp0ztccvFv677bxReeF7p27dpo+2+/HZtMNfirqjZxhNoRhx9aVd+yZcsQR21lleNPODHE6ykECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgbwJ5CrQatu27TTxadeucr2t9H68SevWrSvu1Sa1XzzYqnXjszK2alV9POt+8XpbbrFZuO0ft4a111qzePmqzw3WXy888dhDYa01+4U2bdpUHW/XrsHottvvCB9+9FFVmxOOOzrM3alTVX2siOtqbbXl5lXH4nVuv+POqnoVBAgQIECAAAECBAgQIECAAAECBAgQIECAAIHmFphtUlKauxOz4v2HDRsWBg1+P3z++ahCuDZf926hV69eoWPHOWdFDs9MgAABAgQIECBAgAABAgQIECBAgAABAgQIEKgpINCqSeMAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIBAHgRyNeVgHkD0gQABAgQIECBAgAABAgQIECBAgAABAgQIECBAIF8CAq18vQ+9IUCAAAECBAgQIECAAAECBAgQIECAAAECBAgQSAkItFIgdgkQIECAAAECBAgQIECAAAECBAgQIECAAAECBPIlINDK1/vQGwIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgZSAQCsFYpcAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQCBfAgKtfL0PvSFAgAABAgQIECBAgAABAgQIECBAgAABAgQIEEgJCLRSIHYJECBAgAABAgQIECBAgAABAgQIECBAgAABAgTyJSDQytf70BsCBAgQIECAAAECBAgQIECAAAECBAgQIECAAIGUgEArBWKXAAECBAgQIECAAAECBAgQIECAAAECBAgQIEAgXwICrXy9D70hQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBBICQi0UiB2CRAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIE8iUg0MrX+9AbAgQIECBAgAABAgQIECBAgAABAgQIECBAgACBlIBAKwVilwABAgQIECBAgAABAgQIECBAgAABAgQIECBAIF8CAq18vQ+9IUCAAAECBAgQIECAAAECBAgQIECAAAECBAgQSAkItFIgdgkQIECAAAECBAgQIECAAAECBAgQIECAAAECBPIlINDK1/vQGwIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgZSAQCsFYpcAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQCBfAgKtfL0PvSFAgAABAgQIECBAgAABAgQIECBAgAABAgQIEEgJCLRSIHYJECBAgAABAgQIECBAgAABAgQIECBAgAABAgTyJSDQytf70BsCBAgQIECAAAECBAgQIECAAAECBAgQIECAAIGUgEArBWKXAAECBAgQIECAAAECBAgQIECAAAECBAgQIEAgXwICrXy9D70hQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBBICQi0UiB2CRAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIE8iUg0MrX+9AbAgQIECBAgAABAgQIECBAgAABAgQIECBAgACBlIBAKwVilwABAgQIECBAgAABAgQIECBAgAABAgQIECBAIF8CAq18vQ+9IUCAAAECBAgQIECAAAECBAgQIECAAAECBAgQSAkItFIgdgkQIECAAAECBAgQIECAAAECBAgQIECAAAECBPIlINDK1/vQGwIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgZSAQCsFYpcAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQCBfAgKtfL0PvSFAgAABAgQIECBAgAABAgQIECBAgAABAgQIEEgJCLRSIHYJECBAgAABAgQIECBAgAABAgQIECBAgAABAgTyJSDQytf70BsCBAgQIECAAAECBAgQIECAAAECBAgQIECAAIGUgEArBWKXAAECBAgQIECAAAECBAgQIECAAAECBAgQIEAgXwICrXy9D70hQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBBICQi0UiB2CRAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIE8iUg0MrX+9AbAgQIECBAgAABAgQIECBAgAABAgQIECBAgACBlIBAKwVilwABAgQIECBAgAABAgQIECBAgAABAgQIECBAIF8CAq18vQ+9IUCAAAECBAgQIECAAAECBAgQIECAAAECBAgQSAkItFIgdgkQIECAAAECBAgQIECAAAECBAgQIECAAAECBPIlINDK1/vQGwIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgZRAq9R+s+x++933zXJfNyVAgAABAgQIECBAgAABAgQIECBAgAABAgQIEJg2Au3btp42F8q4ihFaGSiqCBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIE8iMg0MrPu9ATAgQIECBAgAABAgQIECBAgAABAgQIECBAgACBDAGBVgaKKgIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgfwICLTy8y70hAABAgQIECBAgAABAgQIECBAgAABAgQIECBAIENAoJWBoooAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQCA/AgKt/LwLPSFAgAABAgQIECBAgAABAgQIECBAgAABAgQIEMgQEGhloKgiQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBDIj4BAKz/vQk8IECBAgAABAgQIECBAgAABAgQIECBAgAABAgQyBARaGSiqCBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIE8iMg0MrPu9ATAgQIECBAgAABAgQIECBAgAABAgQIECBAgACBDAGBVgaKKgIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgfwICLTy8y70hAABAgQIECBAgAABAgQIECBAgAABAgQIECBAIENAoJWBoooAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQCA/AgKt/LwLPSFAgAABAgQIECBAgAABAgQIECBAgAABAgQIEMgQEGhloKgiQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBDIj4BAKz/vQk8IECBAgAABAgQIECBAgAABAgQIECBAgAABAgQyBARaGSiqCBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIE8iMg0MrPu9ATAgQIECBAgAABAgQIECBAgAABAgQIECBAgACBDAGBVgaKKgIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgfwICLTy8y70hAABAgQIECBAgAABAgQIECBAgAABAgQIECBAIENAoJWBoooAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQCA/AgKt/LwLPSFAgAABAgQIECBAgAABAgQIECBAgAABAgQIEMgQEGhloKgiQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBDIj4BAKz/vQk8IECBAgAABAgQIECBAgAABAgQIECBAgAABAgQyBARaGSiqCBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIE8iMg0MrPu9ATAgQIECBAgAABAgQIECBAgAABAgQIECBAgACBDAGBVgaKKgIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgfwItMpPV/SEAAECBAgQIECAAAECBAgQIECAAAECBAgQIDBrCLz97sBw17/uD/Hzx5TFF104LJb8bLnZRj/mMrk/V6CV+1ekgwQIECBAgAABAgQIECBAgAABAgQIECBAgMDMJHBnEmTddc8D0+SRYiAWfxZfbJEQw62ZtZhycGZ9s56LAAECBAgQIECAAAECBAgQIECAAAECBAgQyKXAOz9yVFbWQ8XRXjNzMUJrZn67no0AAQIECBAgQIAAAQIECBAgQIAAAQIECBDInUD5NIN/vOLCqe5fvM5vf/f7wvnl15zqC+b4RCO0cvxydI0AAQIECBAgQIAAAQIECBAgQIAAAQIECBAgUEtgZp5iMP3MAq20iH0CBAgQIECAAAECBAgQIECAAAECBAgQIECAAIFcCQi0cvU6dIYAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQCAtINBKi9gnQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBDIlYBAK1evQ2cIECBAgAABAgQIECBAgAABAgQIECBAgAABAgTSAgKttIh9AgQIECBAgAABAgQIECBAgAABAgQIECBAgACBXAm0ylVvdIYAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgMAMLvP3uwHDXv+4P8bO8bLHphmHLzTYqr7I9BQICrSnAmlGajh07NkyYMKGquy1btgrt2rWtqldBgACBpgS+//77MG7cuKpms802W+jQoUNVfVbF119/nVUd2rRpE1q3bp15TCUBAj+dwI/974Vp8e/CT/d0M/aVP/98VPIAk8Lss88e2rb1324z9tvUewIECBAgQIAAAQIEZjWBO5Mg6657Hsh87Fgv0MqkqatSoFUX04zV6Jhjjw+PPPJoVafjH0Wef+6ZqvoZpeKll14Of/rzX8K777wbPhoypNTtw395WDjggP1K+9N646uvxoRBgwaFDz/8MHw2cmTo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AAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBHJHgIBW7pQ1V4oAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIRFKAgFYki41MI4AAAggggAACCCCAAAIIIIAAAggggAACCCCAAAK5I0BAK3fKmitFAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBCIpQEArksVGphFAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQACB3BEgoJU7Zc2VIoAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAKRFCCgFcliI9MIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAQO4IENDKnbLmShFAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQACBSAoQ0IpksZFpBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQCB3BAho5U5Zc6UIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAQCQFCGhFstjINAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCQOwIEtHKnrLlSBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQCCSAgS0IllsZBoBBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQyB0BAlq5U9ZcKQIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCAQSQECWpEsNjKNAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCOSOAAGt3ClrrhQBBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQiKQAAa1IFhuZRgABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQRyR4CAVu6UNVeKAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCERSgIBWJIuNTCOAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACuSNAQCt3yporRQABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQiKUBAK5LFRqYRQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAgdwRIKCVO2XNlSKAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACkRTY5nebIplzMo0AAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIJATArTQyoli5iIRQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAgegKENCKbtmRcwQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAgJwQIaOVEMXORCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggEB0BQhoRbfsyDkCCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggkBMCBLRyopi5SAQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAgugIEtKJbduQcAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEMgJAQJaOVHMXCQCCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgggEF0BAlrRLTtyjgACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAgjkhAABrZwoZi4SAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEIiuAAGt6JYdOUcAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEckKAgFZOFDMXiQACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAghEV4CAVnTLjpwjgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAjkhQEArJ4qZi0QAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEoitAQCu6ZUfOEUAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAIGcECCglRPFzEUigAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAtEVIKAV3bIj5wgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIBATggQ0MqJYuYiEUAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAIHoChDQim7ZkXMEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAICcECGjlRDFzkQgggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIBAdAUIaEW37Mg5AggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIJATAgS0cqKYuUgEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAILoCBLSiW3bkHAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBDICQECWjlRzFwkAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIBBdAQJa0S07co4AAggggAACCCCAAAIIIIAAAggggAACCCCAAAII5IQAAa2cKGYuEgEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBCIrgABreiWHTlHAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBHJCgIBWThQzF4kAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIRFfg/wGnDalD+iaBnQAAAABJRU5ErkJggg==" 42 | } 43 | }, 44 | "cell_type": "markdown", 45 | "metadata": {}, 46 | "source": [ 47 | "### Ollama 모델 사용 방법\n", 48 | "![image.png](attachment:image.png)\n", 49 | "- [Ollama 레포지토리](https://github.com/ollama/ollama?tab=readme-ov-file) 참고하여 OS 별 Ollama 다운로드\n", 50 | "- `ollama pull {model_name}` 명령어로 로컬에 모델 다운로드\n", 51 | "- 본 예제에서는 \"gemma2:2b\" 모델 사용 \n", 52 | "\n", 53 | "![image.png](attachment:image.png)\n", 54 | "\n", 55 | "- Ollama 레포지토리에서 모델 라이브러리를 참고하여 원하는 모델 다운로드 가능" 56 | ] 57 | }, 58 | { 59 | "cell_type": "markdown", 60 | "metadata": {}, 61 | "source": [ 62 | "## **2. 모델 로드**\n", 63 | "- Ollama를 이용한 오픈소스 LLM 로드\n", 64 | "- 프롬프트 템플릿 & LLM Chain 생성" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": 2, 70 | "metadata": {}, 71 | "outputs": [], 72 | "source": [ 73 | "# Ollama LLM 설정 (원하는 모델을 선택하여 사용)\n", 74 | "llm = Ollama(model=\"gemma2:2b\")\n", 75 | "\n", 76 | "# 프롬프트 템플릿 생성\n", 77 | "template = \"\"\"\n", 78 | " 질문: {question}\n", 79 | " 답변:\n", 80 | " \"\"\"\n", 81 | "prompt = PromptTemplate(\n", 82 | " input_variables=[\"question\"],\n", 83 | " template=template,\n", 84 | ")\n", 85 | "\n", 86 | "# LLMChain 생성\n", 87 | "llm_chain = LLMChain(prompt=prompt, llm=llm)" 88 | ] 89 | }, 90 | { 91 | "cell_type": "markdown", 92 | "metadata": {}, 93 | "source": [ 94 | "## **3. LLM Q&A 시스템 함수 선언**\n", 95 | "- LLM Chain을 이용해 사용자 질의와 모델 응답을 출력하는 함수\n", 96 | "- 이전 대화 내용은 기억하지 않는 단순한 질의 응답 방법" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": 5, 102 | "metadata": {}, 103 | "outputs": [], 104 | "source": [ 105 | "# 함수 정의: 질문 입력 및 답변 출력\n", 106 | "def QnA_assistant():\n", 107 | " print(\"LLM과의 질의 응답을 시작합니다. 대화 내용은 기억하지 못합니다. 종료하려면 '그만'이라고 입력하세요.\")\n", 108 | " \n", 109 | " while True:\n", 110 | " # 사용자가 질문을 입력\n", 111 | " question = input(\"\\n질문을 입력하세요: \")\n", 112 | "\n", 113 | " # '그만'을 입력하면 종료\n", 114 | " if question.lower() == \"그만\":\n", 115 | " print(\"대화를 종료합니다.\")\n", 116 | " break\n", 117 | "\n", 118 | " # LLMChain을 사용하여 질문에 대한 답변 생성\n", 119 | " response = llm_chain.run(question)\n", 120 | "\n", 121 | " # 질문과 응답을 구분해서 출력\n", 122 | " display(Markdown(f\"### **사용자 질문:**\\n{question}\\n\"))\n", 123 | " display(Markdown(f\"### **LLM 응답:**\\n{response}\"))\n", 124 | " print(\"==========================\")" 125 | ] 126 | }, 127 | { 128 | "cell_type": "markdown", 129 | "metadata": {}, 130 | "source": [ 131 | "## **4. Q&A 진행**\n", 132 | "- LLM에게 질문하고 답변을 받는 과정\n", 133 | "- 대화를 중지하고 싶은 경우 '그만'이라고 입력" 134 | ] 135 | }, 136 | { 137 | "cell_type": "code", 138 | "execution_count": 6, 139 | "metadata": {}, 140 | "outputs": [ 141 | { 142 | "name": "stdout", 143 | "output_type": "stream", 144 | "text": [ 145 | "LLM과의 질의 응답을 시작합니다. 대화 내용은 기억하지 못합니다. 종료하려면 '그만'이라고 입력하세요.\n" 146 | ] 147 | }, 148 | { 149 | "name": "stderr", 150 | "output_type": "stream", 151 | "text": [ 152 | "/var/folders/h7/y4jd7kf533z0n4r3h9x9pc4c0000gn/T/ipykernel_23088/547107013.py:15: LangChainDeprecationWarning: The method `Chain.run` was deprecated in langchain 0.1.0 and will be removed in 1.0. Use :meth:`~invoke` instead.\n", 153 | " response = llm_chain.run(question)\n" 154 | ] 155 | }, 156 | { 157 | "data": { 158 | "text/markdown": [ 159 | "### **사용자 질문:**\n", 160 | "python 언어에 대해 설명해줘\n" 161 | ], 162 | "text/plain": [ 163 | "" 164 | ] 165 | }, 166 | "metadata": {}, 167 | "output_type": "display_data" 168 | }, 169 | { 170 | "data": { 171 | "text/markdown": [ 172 | "### **LLM 응답:**\n", 173 | "## Python 언어에 대한 설명 🐍💻\n", 174 | "\n", 175 | "**Python:** versatile, easy-to-learn programming language 🌎\n", 176 | "\n", 177 | "**무엇 때문에 Python이 인기 있는가? 🤔**\n", 178 | "\n", 179 | "* **쉽게 배우는 방식:** 초보자도 이해하기 쉬운 문법과 유용한 도움말을 통해 시작할 수 있습니다. 😊\n", 180 | "* **다양한 분야에 적용 가능:** Web 개발, 데이터 분석, 머신러닝, 게임 개발 등 거의 모든 분야에서 사용됩니다! 💪\n", 181 | "* **강력하고 활발한 커뮤니티:** 언어를 잘 이해하는 많은 개발자들이 도움을 제공해줍니다. 🤝\n", 182 | "\n", 183 | "**Python의 강점! 🤩**\n", 184 | "\n", 185 | "* **코드가 간결하고 명확:** 문제 해결에 효율적이고 읽기를 용이하게 합니다.\n", 186 | "* **다양한 라이브러리와 기능:** Python은 풍부한 도구들을 제공하여 다양한 작업을 수행할 수 있습니다. 🧰 (예: NumPy, Pandas, matplotlib 등)\n", 187 | "* **안정적인 환경 및 확장성:** 변화에 대한 적응력이 높고 장기적으로 사용하기 위한 안정적입니다. 🚀\n", 188 | "\n", 189 | "**Python 언어 활용 분야! ✨**\n", 190 | "\n", 191 | "* **Web 개발:** Flask, Django로 웹사이트 구축 🌐\n", 192 | "* **데이터 분석:** Pandas, NumPy를 이용하여 데이터 수집, 처리, 분석 💪\n", 193 | "* **머신러닝 & 인공 지능:** Scikit-learn, TensorFlow 등으로 모델 학습 및 예측 🚀\n", 194 | "* **게임 개발:** Pygame와 Kivy로 게임을 만들고 실행 🕹️\n", 195 | "\n", 196 | "\n", 197 | "**Python 언어 배우기 방법! 📖**\n", 198 | "\n", 199 | "* **온라인 강좌 (Coursera, Udemy 등):** 다양한 수준의 과정으로 선택 가능 🎓\n", 200 | "* **프로그래밍 도구 & 환경:** IDE (PyCharm, VS Code)를 통해 실습 💻\n", 201 | "* **실전 연습:** 제공되는 온라인 사례들과 직접 프로젝트 진행 💪\n", 202 | "\n", 203 | "\n", 204 | "**Python 언어는 당신의 창업 꿈을 이룰 수 있는 강력한 도구! 🌠**\n", 205 | "\n", 206 | "더 자세히 알고 싶다면, Python 공식 웹사이트(https://www.python.org/)를 방문해보세요! 😊\n" 207 | ], 208 | "text/plain": [ 209 | "" 210 | ] 211 | }, 212 | "metadata": {}, 213 | "output_type": "display_data" 214 | }, 215 | { 216 | "name": "stdout", 217 | "output_type": "stream", 218 | "text": [ 219 | "==========================\n", 220 | "대화를 종료합니다.\n" 221 | ] 222 | } 223 | ], 224 | "source": [ 225 | "QnA_assistant()" 226 | ] 227 | } 228 | ], 229 | "metadata": { 230 | "kernelspec": { 231 | "display_name": "base", 232 | "language": "python", 233 | "name": "python3" 234 | }, 235 | "language_info": { 236 | "codemirror_mode": { 237 | "name": "ipython", 238 | "version": 3 239 | }, 240 | "file_extension": ".py", 241 | "mimetype": "text/x-python", 242 | "name": "python", 243 | "nbconvert_exporter": "python", 244 | "pygments_lexer": "ipython3", 245 | "version": "3.12.4" 246 | } 247 | }, 248 | "nbformat": 4, 249 | "nbformat_minor": 2 250 | } 251 | -------------------------------------------------------------------------------- /Open-source_LLM/basic_chat/langchain_ollama_chatbot.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# **Langchain과 Ollama를 이용한 대화형 챗봇 예제**\n", 8 | "\n", 9 | "**Langchain**과 **Ollama**를 이용해 **Open-source LLM**으로 대화형 챗봇을 만드는 예제입니다.\n", 10 | "\n", 11 | "\n", 12 | "*본 예제는 구글 코랩 환경이 아닙니다." 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": {}, 18 | "source": [ 19 | "## **1. 환경 세팅**\n", 20 | "- 개발 환경에 필요 라이브러리 설치 : ollama, langchain, langchain_community,...\n", 21 | "- 필요 패키지 임포트\n", 22 | "- Ollama 모델 사용 방법" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": 12, 28 | "metadata": {}, 29 | "outputs": [], 30 | "source": [ 31 | "# 필요한 라이브러리 임포트\n", 32 | "from langchain_community.llms import Ollama\n", 33 | "from langchain_core.prompts import PromptTemplate\n", 34 | "from langchain.chains import LLMChain\n", 35 | "from langchain.memory import ConversationBufferMemory\n", 36 | "from IPython.display import Markdown, display" 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "metadata": {}, 42 | "source": [ 43 | "### Ollama 모델 사용 방법\n", 44 | "- [Ollama 레포지토리](https://github.com/ollama/ollama?tab=readme-ov-file) 참고하여 OS 별 Ollama 다운로드\n", 45 | "- `ollama pull {model_name}` 명령어로 로컬에 모델 다운로드\n", 46 | "- 본 예제에서는 \"gemma2:2b\" 모델 사용 \n", 47 | "- Ollama 레포지토리에서 모델 라이브러리를 참고하여 원하는 모델 다운로드 가능" 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "metadata": {}, 53 | "source": [ 54 | "## **2. 모델 로드**\n", 55 | "- Ollama를 이용한 오픈소스 LLM 로드\n", 56 | "- 프롬프트 템플릿 & LLM Chain 생성\n", 57 | "- 대화 내용을 저장하는 메모리 버퍼 설정" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 13, 63 | "metadata": {}, 64 | "outputs": [], 65 | "source": [ 66 | "# Ollama LLM 설정 (원하는 모델을 선택하여 사용)\n", 67 | "llm = Ollama(model=\"gemma2:2b\")\n", 68 | "\n", 69 | "# 프롬프트 템플릿 생성 (대화의 맥락을 추가)\n", 70 | "template = \"\"\"\n", 71 | " 다음은 사용자와 AI 사이의 대화입니다.\n", 72 | " 대화를 이어서 하세요.\n", 73 | " \n", 74 | " {history}\n", 75 | " \n", 76 | " 사용자: {question}\n", 77 | " AI:\n", 78 | " \"\"\"\n", 79 | "prompt = PromptTemplate(\n", 80 | " input_variables=[\"history\", \"question\"],\n", 81 | " template=template,\n", 82 | ")\n", 83 | "\n", 84 | "# 메모리 설정 (대화 내용을 저장하는 버퍼)\n", 85 | "memory = ConversationBufferMemory(input_key=\"question\", memory_key=\"history\")\n", 86 | "\n", 87 | "# LLMChain 생성 (메모리를 연결)\n", 88 | "llm_chain = LLMChain(prompt=prompt, llm=llm, memory=memory)" 89 | ] 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "metadata": {}, 94 | "source": [ 95 | "## **3. LLM 대화형 챗봇 함수 선언**\n", 96 | "- LLM Chain을 이용해 대화형 챗봇 기능 구현\n", 97 | "- 이전 대화 내용을 기억한 상태로 질의 응답 진행" 98 | ] 99 | }, 100 | { 101 | "cell_type": "code", 102 | "execution_count": 26, 103 | "metadata": {}, 104 | "outputs": [], 105 | "source": [ 106 | "# 함수 정의: 질문 입력 및 답변 출력\n", 107 | "def chatbot_with_memory():\n", 108 | " print(\"대화형 챗봇과의 대화를 시작합니다. 종료하려면 '그만'이라고 입력하세요.\")\n", 109 | " \n", 110 | " while True:\n", 111 | " # 사용자가 질문을 입력\n", 112 | " question = input(\"\\n질문을 입력하세요: \")\n", 113 | "\n", 114 | " # '그만'을 입력하면 종료\n", 115 | " if question.lower() == \"그만\":\n", 116 | " print(\"대화를 종료합니다.\")\n", 117 | " break\n", 118 | "\n", 119 | " # LLMChain을 사용하여 질문에 대한 답변 생성\n", 120 | " response = llm_chain.run(question)\n", 121 | "\n", 122 | " # 질문과 응답을 구분해서 출력\n", 123 | " display(Markdown(f\"### **사용자 질문:**\\n{question}\\n\"))\n", 124 | " display(Markdown(f\"### **LLM 응답:**\\n{response}\"))\n", 125 | " print(\"==========================\")" 126 | ] 127 | }, 128 | { 129 | "cell_type": "markdown", 130 | "metadata": {}, 131 | "source": [ 132 | "## **4. 대화 진행**\n", 133 | "- LLM에게 질문하고 답변을 받는 과정\n", 134 | "- 대화를 중지하고 싶은 경우 '그만'이라고 입력" 135 | ] 136 | }, 137 | { 138 | "cell_type": "code", 139 | "execution_count": 27, 140 | "metadata": {}, 141 | "outputs": [ 142 | { 143 | "name": "stdout", 144 | "output_type": "stream", 145 | "text": [ 146 | "대화형 챗봇과의 대화를 시작합니다. 종료하려면 '그만'이라고 입력하세요.\n" 147 | ] 148 | }, 149 | { 150 | "data": { 151 | "text/markdown": [ 152 | "### **사용자 질문:**\n", 153 | "비타민에 대해 알려줘\n" 154 | ], 155 | "text/plain": [ 156 | "" 157 | ] 158 | }, 159 | "metadata": {}, 160 | "output_type": "display_data" 161 | }, 162 | { 163 | "data": { 164 | "text/markdown": [ 165 | "### **LLM 응답:**\n", 166 | "## 비타민: 우리 몸의 필수적인 영양소! 🌈\n", 167 | "\n", 168 | "비타민은 우리 몸에서 중요한 역할을 하는 **필수적인 영양소**입니다. 💪 다양한 기능을 수행하며 건강 유지에 매우 중요합니다. 😉 \n", 169 | "\n", 170 | "### 비타민 종류와 그 역할들! ✨ \n", 171 | "\n", 172 | "1. **비타민 A (retinol):** 눈, 피부를 위한 강력한 영양소! 👀\n", 173 | " * **눈:** 시야 확보 및 안구 주변 세포 성장 활성화에 필수적! ☀️\n", 174 | " * **피부:** 노화 방지, 탄력 증진 및 윤기 개선에 도움을 줍니다.\n", 175 | "\n", 176 | "2. **비타민 B (B1, B2, B3, B5, B6, B7, B9, B12):** 에너지를 생산하는 데 필수적! 💪\n", 177 | " * **이들의 역할:** 신경 기능 활성화와 신체 작용을 지켜주는 주요 역할입니다. 🧠\n", 178 | "\n", 179 | "3. **비타민 C (Ascorbic Acid):** 면역력 강화에 필수적인 영양소! 💪\n", 180 | " * **피부:** 피부 노화, 미백, 균일성 증진, 피부 질환 예방에 도움을 줄 수 있습니다!\n", 181 | "\n", 182 | "4. **비타민 D (cholecalciferol):** 칼슘 소수와 골밀도 유지에 필수적! 🦴\n", 183 | " * **뼈 건강:** 뼈 성장 및 건강 유지에 필수적입니다. \n", 184 | "\n", 185 | "5. **비타민 E (tocopherols):** 피부 보호, 항산화 작용, 안전을 위한 좋은 영양소!🛡️ \n", 186 | " * **피부:** 자외선 차단, 피부 손상 예방에 도움을 줄 수 있습니다.\n", 187 | "\n", 188 | "### 비타민은 개인별 건강 상태에 따라 필요량이 다릅니다. 🩺\n", 189 | "\n", 190 | "**더 자세한 정보:** 각 비타민의 종류와 필요한 양에 대해 더 알고 싶으신가요? 😊 문자로 질문해주세요! \n", 191 | "\n", 192 | "\n", 193 | "\n" 194 | ], 195 | "text/plain": [ 196 | "" 197 | ] 198 | }, 199 | "metadata": {}, 200 | "output_type": "display_data" 201 | }, 202 | { 203 | "name": "stdout", 204 | "output_type": "stream", 205 | "text": [ 206 | "==========================\n" 207 | ] 208 | }, 209 | { 210 | "data": { 211 | "text/markdown": [ 212 | "### **사용자 질문:**\n", 213 | "B에 대해 조금 더 상세하게 알려줄래?\n" 214 | ], 215 | "text/plain": [ 216 | "" 217 | ] 218 | }, 219 | "metadata": {}, 220 | "output_type": "display_data" 221 | }, 222 | { 223 | "data": { 224 | "text/markdown": [ 225 | "### **LLM 응답:**\n", 226 | "네, 비타민 B에 대한 자세한 정보를 알려드릴게요! 💪\n", 227 | "\n", 228 | "**비타민 B은 우리 몸에서 에너지 생성과 신경 기능 활성화에 필수적인 영양소입니다. ** 총 8종류의 비타민이 포함된 이 군데는 매우 중요합니다. 😎\n", 229 | "\n", 230 | "* **B1 (Thiamine):**\n", 231 | " * **작용:** 미네랄 형태로 에너지 생성을 유도하는 역할을 합니다. 신경계, 심장 및 근육 기능에 도움을 줍니다. 🧠\n", 232 | " * **비타민 B군**: 비타민 B의 일부입니다. \n", 233 | "\n", 234 | "* **B2 (Riboflavin):**\n", 235 | " * **작용:** 세포 성장과 활성화를 위해 에너지를 분해하는 역할을 합니다. 피부, 눈 등에 영향을 미치고 있습니다. 👀\n", 236 | " * **비타민 B군**: 비타민 B의 일부입니다. \n", 237 | "\n", 238 | "* **B3 (Niacin):**\n", 239 | " * **작용:** 세포 성장과 활성화에 필수적인 역할을 합니다. 심혈관 기능 조절에도 중요한 역할을 합니다. 💪🧠\n", 240 | " * **비타민 B군**: 비타민 B의 일부입니다. \n", 241 | "\n", 242 | "* **B5 (Pantothenic Acid):** \n", 243 | " * **작용:** 세포 신호 전달과 에너지 생성에 관여하는 중요한 역할을 합니다. 생산, 소모 및 운동 등에서 활용됩니다. 🧬💪\n", 244 | " * **비타민 B군**: 비타민 B의 일부입니다. \n", 245 | "\n", 246 | "* **B6 (Pyridoxine):** \n", 247 | " * **작용:** 신경계 기능과 신체 작용을 조절하는 역할을 합니다. 뇌, 신장 및 호르몬 분비에 큰 영향을 미치고 있습니다. 🧠💪 \n", 248 | " * **비타민 B군**: 비타민 B의 일부입니다. \n", 249 | "\n", 250 | "* **B7 (Biotin):** \n", 251 | " * **작용:** 카테콜라민 생성과 세포 성장 및 신경 기능에 중요한 역할을 합니다. 피부와 모발 건강에도 도움을 줄 수 있습니다. 🧬💪 \n", 252 | " * **비타민 B군**: 비타민 B의 일부입니다. \n", 253 | "\n", 254 | "* **B9 (Folate):** \n", 255 | " * **작용:** 식물성 생활 유지 및 발달에 필수적인 역할을 합니다. 신체 기능 활동과 성장에 중요한 역할을 합니다. 🧬💪 \n", 256 | " * **비타민 B군**: 비타민 B의 일부입니다.\n", 257 | "\n", 258 | "* **B12 (Cobalamin):** \n", 259 | " * **작용:** 혈액 생성, 신경계 기능 및 기타 생명 활동에 필수적인 역할을 합니다. 치아 건강에도 중요한 역할을 합니다. 🩸🧠🦷 \n", 260 | " * **비타민 B군**: 비타민 B의 일부입니다. \n", 261 | "\n", 262 | "**비타민 B는 우리 몸의 에너지 생산과 신경 기능 활성화에 중요한 역할을 하므로, 건강 관리에 매우 중요합니다! 💪 **\n", 263 | "\n", 264 | "\n", 265 | " 더 자세한 정보를 원하시면 문자로 질문해주세요! 😊" 266 | ], 267 | "text/plain": [ 268 | "" 269 | ] 270 | }, 271 | "metadata": {}, 272 | "output_type": "display_data" 273 | }, 274 | { 275 | "name": "stdout", 276 | "output_type": "stream", 277 | "text": [ 278 | "==========================\n" 279 | ] 280 | }, 281 | { 282 | "data": { 283 | "text/markdown": [ 284 | "### **사용자 질문:**\n", 285 | "어떤 식품을 먹으면 좋아?\n" 286 | ], 287 | "text/plain": [ 288 | "" 289 | ] 290 | }, 291 | "metadata": {}, 292 | "output_type": "display_data" 293 | }, 294 | { 295 | "data": { 296 | "text/markdown": [ 297 | "### **LLM 응답:**\n", 298 | " 비타민 B가 풍부한 식품은 다음과 같습니다. 👍\n", 299 | "\n", 300 | "* **곡류:** 귀리, 잡곡, 현미, 보리와 같은 곡물은 비타민 B1, B2, B6 및 B9를 함유하고 있습니다. 🌾\n", 301 | "* **새우, 연어 등 미네랄이 풍부한 생선:** 새우나 연어는 비타민 B가 풍부합니다. 🐟 \n", 302 | "* **콩과 두부:** 콩과 두부는 비타민 B1을 함유하고 있습니다. 🫘\n", 303 | "* **브로콜리, 시금치 등 채소**: 브로콜리는 비타민 B2를 함유하고 있으며, 시금치와 같은 채소도 비타민 B가 풍부합니다. 🥦 🌱\n", 304 | "\n", 305 | "**비타민 B가 있는 식품을 꾸준히 섭취하면 건강 관리에 도움이 될 수 있습니다.** \n" 306 | ], 307 | "text/plain": [ 308 | "" 309 | ] 310 | }, 311 | "metadata": {}, 312 | "output_type": "display_data" 313 | }, 314 | { 315 | "name": "stdout", 316 | "output_type": "stream", 317 | "text": [ 318 | "==========================\n", 319 | "대화를 종료합니다.\n" 320 | ] 321 | } 322 | ], 323 | "source": [ 324 | "# 챗봇 실행\n", 325 | "chatbot_with_memory()" 326 | ] 327 | } 328 | ], 329 | "metadata": { 330 | "kernelspec": { 331 | "display_name": "base", 332 | "language": "python", 333 | "name": "python3" 334 | }, 335 | "language_info": { 336 | "codemirror_mode": { 337 | "name": "ipython", 338 | "version": 3 339 | }, 340 | "file_extension": ".py", 341 | "mimetype": "text/x-python", 342 | "name": "python", 343 | "nbconvert_exporter": "python", 344 | "pygments_lexer": "ipython3", 345 | "version": "3.12.4" 346 | } 347 | }, 348 | "nbformat": 4, 349 | "nbformat_minor": 2 350 | } 351 | -------------------------------------------------------------------------------- /Open-source_LLM/basic_chat/langchain_ollama_prompting.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# **Langchain과 Ollama를 이용한 프롬프트 엔지니어링 예제**\n", 8 | "\n", 9 | "**Langchain**과 **Ollama**를 이용해 **Open-source LLM**으로 기본적인 프롬프트 엔지니어링을 구현하는 예제입니다.\n", 10 | "\n", 11 | "\n", 12 | "*본 예제는 구글 코랩 환경이 아닙니다." 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": {}, 18 | "source": [ 19 | "## **1. 환경 세팅**\n", 20 | "- 개발 환경에 필요 라이브러리 설치 : ollama, langchain, langchain_community,...\n", 21 | "- 필요 패키지 임포트\n", 22 | "- Ollama 모델 사용 방법" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": 1, 28 | "metadata": {}, 29 | "outputs": [], 30 | "source": [ 31 | "from langchain_community.llms import Ollama\n", 32 | "from langchain_core.prompts import PromptTemplate\n", 33 | "from langchain.chains import LLMChain\n", 34 | "from IPython.display import Markdown, display" 35 | ] 36 | }, 37 | { 38 | "cell_type": "markdown", 39 | "metadata": {}, 40 | "source": [ 41 | "### Ollama 모델 사용 방법\n", 42 | "- [Ollama 레포지토리](https://github.com/ollama/ollama?tab=readme-ov-file) 참고하여 OS 별 Ollama 다운로드\n", 43 | "- `ollama pull {model_name}` 명령어로 로컬에 모델 다운로드\n", 44 | "- 본 예제에서는 \"gemma2:2b\" 모델 사용 \n", 45 | "- Ollama 레포지토리에서 모델 라이브러리를 참고하여 원하는 모델 다운로드 가능" 46 | ] 47 | }, 48 | { 49 | "cell_type": "markdown", 50 | "metadata": {}, 51 | "source": [ 52 | "## **2. 모델 로드**\n", 53 | "- Ollama를 이용한 오픈소스 LLM 로드\n", 54 | " - temperature, top_p 등 하이퍼파라미터 조정\n", 55 | "- 프롬프트 템플릿 & LLM Chain 생성\n", 56 | " - 템플릿을 구성하여 프롬프트 엔지니어링 준비" 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "execution_count": 2, 62 | "metadata": {}, 63 | "outputs": [ 64 | { 65 | "name": "stderr", 66 | "output_type": "stream", 67 | "text": [ 68 | "/var/folders/h7/y4jd7kf533z0n4r3h9x9pc4c0000gn/T/ipykernel_32179/2297175553.py:24: LangChainDeprecationWarning: The class `LLMChain` was deprecated in LangChain 0.1.17 and will be removed in 1.0. Use :meth:`~RunnableSequence, e.g., `prompt | llm`` instead.\n", 69 | " llm_chain = LLMChain(prompt=prompt, llm=llm)\n" 70 | ] 71 | } 72 | ], 73 | "source": [ 74 | "# Ollama LLM 설정 (하이퍼파라미터 조정: temperature, top_p)\n", 75 | "llm = Ollama(\n", 76 | " model=\"gemma2:2b\", \n", 77 | " temperature=0.7, # 창의성을 적당히 높임\n", 78 | " top_p=0.9 # 확률 분포의 상위 90%에서 샘플링\n", 79 | ")\n", 80 | "\n", 81 | "# 프롬프트 템플릿 (프롬프트 엔지니어링 적용)\n", 82 | "template = \"\"\"\n", 83 | "context를 고려하여 답변을 생성해주세요.\n", 84 | "\n", 85 | "context: {context}\n", 86 | "\n", 87 | "질문: {question}\n", 88 | "답변:\"\"\"\n", 89 | "\n", 90 | "# 상황과 질문을 받아 모델이 응답하도록 하는 PromptTemplate\n", 91 | "prompt = PromptTemplate(\n", 92 | " input_variables=[\"context\", \"question\"],\n", 93 | " template=template,\n", 94 | ")\n", 95 | "\n", 96 | "# LLMChain 생성\n", 97 | "llm_chain = LLMChain(prompt=prompt, llm=llm)" 98 | ] 99 | }, 100 | { 101 | "cell_type": "markdown", 102 | "metadata": {}, 103 | "source": [ 104 | "## **3. Context 기반 질의 응답**\n", 105 | "- Context를 고려한 질의 응답 진행을 위해 윷놀이 규칙이 담긴 문서 준비\n", 106 | "- Context 고려한 질의 응답 진행\n", 107 | " - 위 코드 template에서 context를 고려하여 답변하도록 프롬프트 작성" 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": 3, 113 | "metadata": {}, 114 | "outputs": [], 115 | "source": [ 116 | "# 상황과 질문을 정의\n", 117 | "context = \"\"\"\n", 118 | "윷놀이 규칙\n", 119 | "1. 준비물\n", 120 | "\n", 121 | "윷: 앞뒤가 다른 네 개의 막대.\n", 122 | "윷판: 원형 모양의 판, 중앙으로 가는 지름길이 있습니다.\n", 123 | "말: 각 팀이 사용할 말 4개.\n", 124 | "2. 플레이어\n", 125 | "\n", 126 | "최소 2명에서 4명까지 팀을 이루어 플레이합니다.\n", 127 | "3. 윷 던지기 윷은 네 개의 막대로 구성되어 있으며, 던진 결과에 따라 다음과 같은 점수를 얻습니다:\n", 128 | "\n", 129 | "도: 1칸 이동 (1개만 뒤집힘)\n", 130 | "개: 2칸 이동 (2개 뒤집힘)\n", 131 | "걸: 3칸 이동 (3개 뒤집힘)\n", 132 | "윷: 4칸 이동 (4개 모두 뒤집힘)\n", 133 | "모: 5칸 이동 (모두 안 뒤집힘)\n", 134 | "4. 말 이동\n", 135 | "\n", 136 | "윷이나 모가 나오면 한 번 더 던질 수 있습니다.\n", 137 | "말을 이동시키며, 자신의 말 4개가 모두 완주하면 승리합니다.\n", 138 | "5. 말 업기\n", 139 | "\n", 140 | "같은 팀의 말이 한 칸에 모이면 말 업기가 가능합니다. 업힌 말은 함께 이동합니다.\n", 141 | "6. 잡기\n", 142 | "\n", 143 | "상대방의 말을 잡으면, 상대방 말은 시작점으로 돌아갑니다. 잡은 플레이어는 한 번 더 윷을 던집니다.\n", 144 | "7. 승리 조건\n", 145 | "\n", 146 | "자신의 말 4개를 모두 완주시키면 승리합니다.\n", 147 | "특별 규칙\n", 148 | "지름길: 중앙으로 가는 지름길을 통해 빠르게 이동할 수 있습니다.\n", 149 | "말의 이동 선택: 윷을 던질 때, 여러 개의 말 중 어느 말이 이동할지 선택할 수 있습니다.\n", 150 | "윷놀이는 간단하면서도 전략적인 게임으로, 운과 실력을 모두 요구하는 한국 전통 놀이입니다.\n", 151 | "\"\"\"" 152 | ] 153 | }, 154 | { 155 | "cell_type": "code", 156 | "execution_count": 4, 157 | "metadata": {}, 158 | "outputs": [ 159 | { 160 | "name": "stderr", 161 | "output_type": "stream", 162 | "text": [ 163 | "/var/folders/h7/y4jd7kf533z0n4r3h9x9pc4c0000gn/T/ipykernel_32179/1700282676.py:3: LangChainDeprecationWarning: The method `Chain.run` was deprecated in langchain 0.1.0 and will be removed in 1.0. Use :meth:`~invoke` instead.\n", 164 | " response = llm_chain.run(context=context, question=question)\n" 165 | ] 166 | }, 167 | { 168 | "name": "stdout", 169 | "output_type": "stream", 170 | "text": [ 171 | "LLM 답변:\n" 172 | ] 173 | }, 174 | { 175 | "data": { 176 | "text/markdown": [ 177 | "윷놀이에서 상대방의 말을 잡으면, **상대방 말은 시작점으로 돌아갑니다.** 그리고 잡은 플레이어는 한 번 더 윷을 던질 수 있습니다. \n" 178 | ], 179 | "text/plain": [ 180 | "" 181 | ] 182 | }, 183 | "execution_count": 4, 184 | "metadata": {}, 185 | "output_type": "execute_result" 186 | } 187 | ], 188 | "source": [ 189 | "question = \"윷놀이에서 상대방 말을 잡으면 어떻게 돼?\"\n", 190 | "\n", 191 | "response = llm_chain.run(context=context, question=question)\n", 192 | "print(\"LLM 답변:\")\n", 193 | "Markdown(response)" 194 | ] 195 | }, 196 | { 197 | "cell_type": "markdown", 198 | "metadata": {}, 199 | "source": [ 200 | "## **4. Few-shot Learning 질의 응답**\n", 201 | "- Few-shot Learning 방법 예시" 202 | ] 203 | }, 204 | { 205 | "cell_type": "code", 206 | "execution_count": 5, 207 | "metadata": {}, 208 | "outputs": [], 209 | "source": [ 210 | "# Few-shot Learning 추가 예시 (Few-shot을 통한 학습 예제 제공)\n", 211 | "few_shot_template = \"\"\"\n", 212 | "다음 질문 - 답변 형식에 맞게 답변을 생성해주세요\n", 213 | "\n", 214 | "1. 질문: AI 연구를 시작하려면 어떤 것을 공부해야 하나요?\n", 215 | " 답변: 기초 프로그래밍, 선형대수학, 확률론, 그리고 기본적인 머신러닝 개념을 공부해야 합니다.\n", 216 | "\n", 217 | "2. 질문: 딥러닝을 공부하기 전에 필요한 기초 지식은 무엇인가요?\n", 218 | " 답변: 미적분학, 행렬 연산, 확률분포, 그리고 그래디언트 기반 최적화 기법을 숙지해야 합니다.\n", 219 | "\n", 220 | "3. 질문: {question}\n", 221 | " 답변:\n", 222 | "\"\"\"\n", 223 | "\n", 224 | "few_shot_prompt = PromptTemplate(\n", 225 | " input_variables=[\"question\"],\n", 226 | " template=few_shot_template,\n", 227 | ")\n", 228 | "llm_chain_few_shot = LLMChain(prompt=few_shot_prompt, llm=llm)" 229 | ] 230 | }, 231 | { 232 | "cell_type": "code", 233 | "execution_count": 6, 234 | "metadata": {}, 235 | "outputs": [ 236 | { 237 | "name": "stdout", 238 | "output_type": "stream", 239 | "text": [ 240 | "Few-shot Learning 기반 LLM 답변:\n" 241 | ] 242 | }, 243 | { 244 | "data": { 245 | "text/markdown": [ 246 | "강화학습을 공부하려면 다음과 같은 지식이 필요합니다.\n", 247 | "\n", 248 | "* **머신러닝 기초**: AI의 핵심 개념들을 이해하는 것이 중요합니다. 특히 학습 과정, 모델 구조, 데이터 처리 등에 대한 이해가 필요합니다.\n", 249 | "* **기하학적 접근**: 강화학습은 특수한 변수와 관계를 분석하여 모델을 학습시키는 방식입니다. 이러한 접근방식을 이해해야 합니다. \n", 250 | "\n", 251 | "강화학습은 다양한 분야에서 활용되는 복잡한 알고리즘이므로, 기초 지식을 바탕으로 구체적인 방법과 정의를 파악하는 것이 중요합니다.\n", 252 | "\n", 253 | "\n", 254 | "**추가적으로**:\n", 255 | "\n", 256 | "* **Python:** 강화학습을 위한 주요 언어입니다. \n", 257 | "* **numpy**: Python에서 데이터 처리 및 계산에 사용되는 라이브러리 \n", 258 | "\n", 259 | "\n", 260 | "\n" 261 | ], 262 | "text/plain": [ 263 | "" 264 | ] 265 | }, 266 | "execution_count": 6, 267 | "metadata": {}, 268 | "output_type": "execute_result" 269 | } 270 | ], 271 | "source": [ 272 | "# 사용자 질문에 few-shot으로 응답\n", 273 | "\n", 274 | "question = \"강화학습을 공부하려면 무엇을 알아야 하나요?\"\n", 275 | "\n", 276 | "response_few_shot = llm_chain_few_shot.run(question=question)\n", 277 | "print(\"Few-shot Learning 기반 LLM 답변:\")\n", 278 | "Markdown(response_few_shot)" 279 | ] 280 | } 281 | ], 282 | "metadata": { 283 | "kernelspec": { 284 | "display_name": "base", 285 | "language": "python", 286 | "name": "python3" 287 | }, 288 | "language_info": { 289 | "codemirror_mode": { 290 | "name": "ipython", 291 | "version": 3 292 | }, 293 | "file_extension": ".py", 294 | "mimetype": "text/x-python", 295 | "name": "python", 296 | "nbconvert_exporter": "python", 297 | "pygments_lexer": "ipython3", 298 | "version": "3.12.4" 299 | } 300 | }, 301 | "nbformat": 4, 302 | "nbformat_minor": 2 303 | } 304 | -------------------------------------------------------------------------------- /Open-source_LLM/rag/llama-index_ollama_RAG_basic.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# **Ollama와 llama_index를 활용한 RAG 기본 예제**\n", 8 | "\n", 9 | "**Ollama**, **llama_index** 등의 라이브러리를 이용해 **Open-source LLM**으로 기본적인 **RAG** 기능을 구현하는 예제입니다.\n", 10 | "\n", 11 | "- Ollama : LLM 모델 \n", 12 | "- llama_index : RAG 문서 데이터셋\n", 13 | "- sentence_transformers : 텍스트 임베딩 모델\n", 14 | "\n", 15 | "\n", 16 | "*본 예제는 구글 코랩 환경이 아닙니다." 17 | ] 18 | }, 19 | { 20 | "cell_type": "markdown", 21 | "metadata": {}, 22 | "source": [ 23 | "## **1. 환경 세팅**\n", 24 | "- 개발 환경에 필요 라이브러리 설치 : ollama, langchain, langchain_community,...\n", 25 | "- 필요 패키지 임포트\n", 26 | "- Ollama 모델 사용 방법\n", 27 | "- `search_related_docs`\n", 28 | " - 질의와 관련된 문서를 검색하는 함수\n", 29 | " - query 임베딩을 생성하고 유사도가 높은 문서를 찾음" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": 29, 35 | "metadata": {}, 36 | "outputs": [], 37 | "source": [ 38 | "from langchain.llms import Ollama\n", 39 | "from llama_index.core import Document\n", 40 | "from sentence_transformers import SentenceTransformer, util\n", 41 | "from IPython.display import Markdown, display" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 30, 47 | "metadata": {}, 48 | "outputs": [], 49 | "source": [ 50 | "def search_related_docs(embedding_model, query, documents):\n", 51 | "# 질의 임베딩 생성\n", 52 | " query_embedding = embedding_model.encode(query)\n", 53 | " # 인덱스를 사용하여 관련 문서 검색\n", 54 | " doc_embeddings = embedding_model.encode([doc.text for doc in documents])\n", 55 | " cosine_scores = util.pytorch_cos_sim(query_embedding, doc_embeddings)\n", 56 | "\n", 57 | " # 상위 N개의 관련 문서 인덱스 찾기\n", 58 | " top_k = 2\n", 59 | " top_results = cosine_scores[0].topk(top_k)\n", 60 | "\n", 61 | " # 관련 문서 추출\n", 62 | " related_docs = [documents[idx].text for idx in top_results[1]]\n", 63 | "\n", 64 | " return related_docs" 65 | ] 66 | }, 67 | { 68 | "cell_type": "markdown", 69 | "metadata": {}, 70 | "source": [ 71 | "### Ollama 모델 사용 방법\n", 72 | "- [Ollama 레포지토리](https://github.com/ollama/ollama?tab=readme-ov-file) 참고하여 OS 별 Ollama 다운로드\n", 73 | "- `ollama pull {model_name}` 명령어로 로컬에 모델 다운로드\n", 74 | "- 본 예제에서는 \"gemma2:2b\" 모델 사용 \n", 75 | "- Ollama 레포지토리에서 모델 라이브러리를 참고하여 원하는 모델 다운로드 가능" 76 | ] 77 | }, 78 | { 79 | "cell_type": "markdown", 80 | "metadata": {}, 81 | "source": [ 82 | "## **2. 모델 로드**\n", 83 | "- Ollama를 이용한 오픈소스 LLM 로드\n", 84 | "- `SentenceTransformer` 의 텍스트 임베딩 모델 로드\n", 85 | " - 한국어 임베딩이 가능한 \"distiluse-base-multilingual-cased-v1\" 모델 사용" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": 31, 91 | "metadata": {}, 92 | "outputs": [ 93 | { 94 | "name": "stderr", 95 | "output_type": "stream", 96 | "text": [ 97 | "/opt/anaconda3/lib/python3.12/site-packages/transformers/tokenization_utils_base.py:1601: FutureWarning: `clean_up_tokenization_spaces` was not set. It will be set to `True` by default. This behavior will be depracted 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\n", 98 | " warnings.warn(\n" 99 | ] 100 | } 101 | ], 102 | "source": [ 103 | "# Ollama 모델 로드\n", 104 | "llm = Ollama(model='gemma2:2b') # 사용할 Ollama 모델 선택\n", 105 | "\n", 106 | "# 텍스트 임베딩 모델 로드\n", 107 | "# distiluse-base-multilingual-cased-v1 : 한국어 임베딩을 지원하는 모델\n", 108 | "# embedding_model = SentenceTransformer('all-mpnet-base-v2')\n", 109 | "embedding_model = SentenceTransformer('distiluse-base-multilingual-cased-v1')" 110 | ] 111 | }, 112 | { 113 | "cell_type": "markdown", 114 | "metadata": {}, 115 | "source": [ 116 | "## **3. RAG 문서 데이터셋 정의**\n", 117 | "- RAG에서 검색할 텍스트 데이터셋 정의\n", 118 | "- `Documents` 객체를 생성하여 각 텍스트를 문서로 변환\n", 119 | "- 예제에서는 윷놀이, 제기차기, 식혜 만들기, 스타크래프트에 대한 문서 사용" 120 | ] 121 | }, 122 | { 123 | "cell_type": "code", 124 | "execution_count": 32, 125 | "metadata": {}, 126 | "outputs": [], 127 | "source": [ 128 | "text_0 = \"\"\"\n", 129 | "윷놀이 규칙\n", 130 | "1. 준비물\n", 131 | "\n", 132 | "윷: 앞뒤가 다른 네 개의 막대.\n", 133 | "윷판: 원형 모양의 판, 중앙으로 가는 지름길이 있습니다.\n", 134 | "말: 각 팀이 사용할 말 4개.\n", 135 | "2. 플레이어\n", 136 | "\n", 137 | "최소 2명에서 4명까지 팀을 이루어 플레이합니다.\n", 138 | "3. 윷 던지기 윷은 네 개의 막대로 구성되어 있으며, 던진 결과에 따라 다음과 같은 점수를 얻습니다:\n", 139 | "\n", 140 | "도: 1칸 이동 (1개만 뒤집힘)\n", 141 | "개: 2칸 이동 (2개 뒤집힘)\n", 142 | "걸: 3칸 이동 (3개 뒤집힘)\n", 143 | "윷: 4칸 이동 (4개 모두 뒤집힘)\n", 144 | "모: 5칸 이동 (모두 안 뒤집힘)\n", 145 | "4. 말 이동\n", 146 | "\n", 147 | "윷이나 모가 나오면 한 번 더 던질 수 있습니다.\n", 148 | "말을 이동시키며, 자신의 말 4개가 모두 완주하면 승리합니다.\n", 149 | "5. 말 업기\n", 150 | "\n", 151 | "같은 팀의 말이 한 칸에 모이면 말 업기가 가능합니다. 업힌 말은 함께 이동합니다.\n", 152 | "6. 잡기\n", 153 | "\n", 154 | "상대방의 말을 잡으면, 상대방 말은 시작점으로 돌아갑니다. 잡은 플레이어는 한 번 더 윷을 던집니다.\n", 155 | "7. 승리 조건\n", 156 | "\n", 157 | "자신의 말 4개를 모두 완주시키면 승리합니다.\n", 158 | "특별 규칙\n", 159 | "지름길: 중앙으로 가는 지름길을 통해 빠르게 이동할 수 있습니다.\n", 160 | "말의 이동 선택: 윷을 던질 때, 여러 개의 말 중 어느 말이 이동할지 선택할 수 있습니다.\n", 161 | "윷놀이는 간단하면서도 전략적인 게임으로, 운과 실력을 모두 요구하는 한국 전통 놀이입니다.\"\"\"\n", 162 | "\n", 163 | "text_1 =\"\"\"\n", 164 | "제기차기는 한국의 전통 놀이로, 주로 어린이들이 즐기는 활동입니다. 제기차기의 기본 규칙은 다음과 같습니다:\n", 165 | "\n", 166 | "제기 만들기: 제기는 주로 종이나 천으로 만들어진 둥글고 평평한 물체입니다. 흔히 종이로 만든 제기를 사용하며, 발 아래에 적당한 무게가 있는 경우가 많습니다.\n", 167 | "\n", 168 | "차기: 플레이어는 제기를 발로 차서 공중으로 띄웁니다. 제기가 땅에 떨어지기 전에 다시 차서 계속 공중에 띄워야 합니다.\n", 169 | "\n", 170 | "점수 시스템: 제기를 공중에 얼마나 많이 띄우는지에 따라 점수를 매깁니다. 특정 횟수 이상을 차면 점수를 부여할 수 있습니다.\n", 171 | "\n", 172 | "대결: 여러 명이 함께 제기차기를 하며, 서로의 제기를 방해하거나 더 높은 점수를 내는 방식으로 대결할 수 있습니다.\n", 173 | "\n", 174 | "규칙 변형: 지역이나 그룹에 따라 제기차기 방식이나 규칙이 다를 수 있으며, 다양한 변형 규칙이 존재합니다.\n", 175 | "\n", 176 | "제기차기는 신체 운동과 협동심을 기르는 데 도움이 되는 놀이입니다!\n", 177 | "\"\"\"\n", 178 | "\n", 179 | "text_2 =\"\"\"\n", 180 | "식혜는 한국의 전통적인 단 음료로, 주로 명절이나 특별한 날에 즐겨 먹습니다. 식혜 만드는 방법은 다음과 같습니다:\n", 181 | "\n", 182 | "재료\n", 183 | "찹쌀: 1컵\n", 184 | "물: 6컵\n", 185 | "엿기름: 1/2컵 (또는 엿기름 가루)\n", 186 | "설탕: 1/2컵 (취향에 따라 조절)\n", 187 | "소금: 약간\n", 188 | "계피: (선택 사항)\n", 189 | "생강: (선택 사항)\n", 190 | "만들기\n", 191 | "찹쌀 준비: 찹쌀을 깨끗이 씻어 3-4시간 정도 불립니다. 불린 찹쌀은 체에 받쳐 물기를 빼둡니다.\n", 192 | "\n", 193 | "엿기름 추출: 엿기름을 물에 담가 1시간 정도 우려냅니다. 우린 물은 따로 준비해 두고 엿기름은 체에 걸러서 버립니다.\n", 194 | "\n", 195 | "찹쌀 찌기: 불린 찹쌀을 찜통에 넣고 20-30분 정도 쪄서 익힙니다. 완전히 익힌 후에는 식혀 둡니다.\n", 196 | "\n", 197 | "조리: 큰 냄비에 엿기름 물, 물 6컵을 넣고 끓입니다. 끓어오르면 불을 줄이고, 식힌 찹쌀을 넣습니다. 약한 불에서 30분 정도 끓입니다.\n", 198 | "\n", 199 | "설탕과 소금 추가: 끓인 후 설탕과 소금을 넣고, 다시 약한 불에서 10분 정도 더 끓입니다. 이때 계피나 생강을 추가하면 향이 더해집니다.\n", 200 | "\n", 201 | "식히기: 식혜가 완성되면 체에 걸러서 고운 식혜를 만듭니다. 체에 걸러낸 찹쌀은 다른 요리에 활용할 수 있습니다.\n", 202 | "\n", 203 | "냉장 보관: 식혜는 냉장고에 보관하면 더욱 맛있게 즐길 수 있습니다. 차갑게 해서 마시면 좋습니다!\"\"\"\n", 204 | "\n", 205 | "text_3 =\"\"\"\n", 206 | "스타크래프트(StarCraft)는 블리자드 엔터테인먼트가 개발한 실시간 전략(RTS) 게임으로, 1998년에 처음 출시되었습니다. 이 게임은 주로 미래의 우주 전쟁을 배경으로 하며, 세 가지 종족인 테란(Terran), 저그(Zerg), 프로토스(Protoss) 간의 전투를 중심으로 진행됩니다. 주요 특징은 다음과 같습니다:\n", 207 | "\n", 208 | "주요 특징\n", 209 | "종족:\n", 210 | "\n", 211 | "테란: 인간 기반의 종족으로, 기계적 유닛과 다양한 건물을 사용합니다. 전략적인 방어와 기동성이 강점입니다.\n", 212 | "저그: 생물학적 유닛으로 구성된 종족으로, 빠른 생산 속도와 대규모 군대를 특징으로 합니다. 유연한 전술이 가능합니다.\n", 213 | "프로토스: 고도로 발달된 외계 종족으로, 강력한 기술과 방어력을 가진 유닛을 보유하고 있습니다. 자원 관리가 중요합니다.\n", 214 | "게임 모드:\n", 215 | "\n", 216 | "싱글 플레이어: 캠페인 모드에서 스토리를 따라 미션을 수행합니다.\n", 217 | "멀티 플레이어: 다른 플레이어와 대결하거나 팀을 이루어 경쟁하는 방식입니다. e스포츠 대회도 활발하게 열립니다.\n", 218 | "전략: 자원 관리, 유닛 생산, 기술 개발, 전투 전략 등을 결합하여 승리를 목표로 합니다. 각 종족의 특성을 잘 활용하는 것이 중요합니다.\n", 219 | "\n", 220 | "e스포츠: 스타크래프트는 e스포츠의 선두주자로, 다양한 대회와 리그가 열리고 있으며, 많은 프로게이머들이 활동하고 있습니다.\n", 221 | "\n", 222 | "확장팩: 스타크래프트는 이후 스타크래프트: 브루드 워와 같은 확장팩이 출시되어 새로운 유닛과 기능을 추가했습니다.\n", 223 | "\n", 224 | "스타크래프트는 그 깊이 있는 전략성과 독창적인 세계관 덕분에 많은 사랑을 받고 있으며, RTS 장르의 대표작으로 자리잡고 있습니다.\n", 225 | "\"\"\"" 226 | ] 227 | }, 228 | { 229 | "cell_type": "code", 230 | "execution_count": 33, 231 | "metadata": {}, 232 | "outputs": [], 233 | "source": [ 234 | "# 문서 데이터셋 생성\n", 235 | "documents = [\n", 236 | " Document(text=text_0),\n", 237 | " Document(text=text_1),\n", 238 | " Document(text=text_2),\n", 239 | " Document(text=text_3)\n", 240 | "]" 241 | ] 242 | }, 243 | { 244 | "cell_type": "markdown", 245 | "metadata": {}, 246 | "source": [ 247 | "## **4. 질의 및 문서 검색**\n", 248 | "- 사용자 질의와 가장 유사한 참고 문서를 검색하고,\n", 249 | "- 검색된 관련 문서를 바탕으로 LLM 모델 응답을 생성" 250 | ] 251 | }, 252 | { 253 | "cell_type": "markdown", 254 | "metadata": {}, 255 | "source": [ 256 | "### 스타크래프트 관련 질의" 257 | ] 258 | }, 259 | { 260 | "cell_type": "code", 261 | "execution_count": 34, 262 | "metadata": {}, 263 | "outputs": [ 264 | { 265 | "name": "stdout", 266 | "output_type": "stream", 267 | "text": [ 268 | "질문: 스타크래프트 종족별 특징에 대해 알려줘\n", 269 | "관련 문서: ['\\n스타크래프트(StarCraft)는 블리자드 엔터테인먼트가 개발한 실시간 전략(RTS) 게임으로, 1998년에 처음 출시되었습니다. 이 게임은 주로 미래의 우주 전쟁을 배경으로 하며, 세 가지 종족인 테란(Terran), 저그(Zerg), 프로토스(Protoss) 간의 전투를 중심으로 진행됩니다. 주요 특징은 다음과 같습니다:\\n\\n주요 특징\\n종족:\\n\\n테란: 인간 기반의 종족으로, 기계적 유닛과 다양한 건물을 사용합니다. 전략적인 방어와 기동성이 강점입니다.\\n저그: 생물학적 유닛으로 구성된 종족으로, 빠른 생산 속도와 대규모 군대를 특징으로 합니다. 유연한 전술이 가능합니다.\\n프로토스: 고도로 발달된 외계 종족으로, 강력한 기술과 방어력을 가진 유닛을 보유하고 있습니다. 자원 관리가 중요합니다.\\n게임 모드:\\n\\n싱글 플레이어: 캠페인 모드에서 스토리를 따라 미션을 수행합니다.\\n멀티 플레이어: 다른 플레이어와 대결하거나 팀을 이루어 경쟁하는 방식입니다. e스포츠 대회도 활발하게 열립니다.\\n전략: 자원 관리, 유닛 생산, 기술 개발, 전투 전략 등을 결합하여 승리를 목표로 합니다. 각 종족의 특성을 잘 활용하는 것이 중요합니다.\\n\\ne스포츠: 스타크래프트는 e스포츠의 선두주자로, 다양한 대회와 리그가 열리고 있으며, 많은 프로게이머들이 활동하고 있습니다.\\n\\n확장팩: 스타크래프트는 이후 스타크래프트: 브루드 워와 같은 확장팩이 출시되어 새로운 유닛과 기능을 추가했습니다.\\n\\n스타크래프트는 그 깊이 있는 전략성과 독창적인 세계관 덕분에 많은 사랑을 받고 있으며, RTS 장르의 대표작으로 자리잡고 있습니다.\\n', '\\n제기차기는 한국의 전통 놀이로, 주로 어린이들이 즐기는 활동입니다. 제기차기의 기본 규칙은 다음과 같습니다:\\n\\n제기 만들기: 제기는 주로 종이나 천으로 만들어진 둥글고 평평한 물체입니다. 흔히 종이로 만든 제기를 사용하며, 발 아래에 적당한 무게가 있는 경우가 많습니다.\\n\\n차기: 플레이어는 제기를 발로 차서 공중으로 띄웁니다. 제기가 땅에 떨어지기 전에 다시 차서 계속 공중에 띄워야 합니다.\\n\\n점수 시스템: 제기를 공중에 얼마나 많이 띄우는지에 따라 점수를 매깁니다. 특정 횟수 이상을 차면 점수를 부여할 수 있습니다.\\n\\n대결: 여러 명이 함께 제기차기를 하며, 서로의 제기를 방해하거나 더 높은 점수를 내는 방식으로 대결할 수 있습니다.\\n\\n규칙 변형: 지역이나 그룹에 따라 제기차기 방식이나 규칙이 다를 수 있으며, 다양한 변형 규칙이 존재합니다.\\n\\n제기차기는 신체 운동과 협동심을 기르는 데 도움이 되는 놀이입니다!\\n']\n" 270 | ] 271 | } 272 | ], 273 | "source": [ 274 | "query = \"스타크래프트 종족별 특징에 대해 알려줘\"\n", 275 | "related_docs = search_related_docs(embedding_model, query, documents)\n", 276 | "print(\"질문:\", query)\n", 277 | "print(\"관련 문서:\", related_docs)" 278 | ] 279 | }, 280 | { 281 | "cell_type": "code", 282 | "execution_count": 35, 283 | "metadata": {}, 284 | "outputs": [ 285 | { 286 | "data": { 287 | "text/markdown": [ 288 | "## 스타크래프트 종족별 특징 및 정보 \n", 289 | "\n", 290 | "**1. 테란 (Terran):** 인간 종족으로, **기계적 유닛과 다양한 건물을 활용**합니다. 🤖💪 \n", 291 | "\n", 292 | " * **강점:** 전략적인 방어와 기동성이 우수하며, 여러 가지 기술과 유닛들을 사용하여 적극적으로 공격하고 방어할 수 있습니다.\n", 293 | " * **특징:**\n", 294 | " * **인간적인 지휘**: 인공지능을 활용한 다양한 기술로 전략적인 플레이와 실제 상황을 고려하는 경험이 풍부합니다. 🧠 \n", 295 | " * **기계적 강점**: 주력 유닛은 기계적으로 효율적인 공격과 지원 기능을 가집니다.\n", 296 | " * **대규모 군사:** 다양한 전문 지휘관을 통해 병사의 효율성과 공격력을 높여줍니다. ⚔️\n", 297 | "\n", 298 | "**2. 저그 (Zerg):** 생물학적 유닛으로 구성된 종족입니다. 🦠💥 \n", 299 | " * **강점:** 빠른 생산 속도와 대규모 군대를 특징으로 합니다. ⚡️💪 \n", 300 | " * **특징:**\n", 301 | " * **생물학적 강점**: 공격적인 전투 스타일을 통해 적의 유닛을 파괴하고 진행할 수 있습니다. 💥 \n", 302 | " * **공격력**: 생리적으로 능률적이고 폭발적인 공격력으로 상대방을 빠르게 공격합니다. 💣 \n", 303 | "\n", 304 | "**3. 프로토스 (Protoss):** 고도로 발달된 외계 종족입니다. 🌟🌌 \n", 305 | " * **강점:** 강력한 기술과 방어력을 가진 유닛을 보유하고 있습니다. 🛡️💪 \n", 306 | " * **특징:**\n", 307 | " * **지속적인 상대방**: 장기 전투를 통해 생존 확률을 높일 수 있습니다. ⏳\n", 308 | " * **자원 관리**: 전략적 조절과 끊임없는 개발 노력이 필요합니다. ⚙️ \n", 309 | "\n", 310 | "**4. 스타크래프트 종족 특징 요약:**\n", 311 | "\n", 312 | "| 종족 | 유닛 & 기술 | 강점 | 특징 | \n", 313 | "|---|---|---|---| \n", 314 | "| 테란 | 기계적 유닛, 다양한 건물 | 전략적인 방어/기동성 | 인간 지휘와 기술을 활용해 승리 |\n", 315 | "| 저그 | 생물학적 유닛 | 빠른 생산 속도 & 대규모 군대 | 공격적인 전투 스타일 | \n", 316 | "| 프로토스 | 강력한 기술, 방어력 | 지속적인 상대방 및 자원 관리 | 장기전투와 기술적인 우위 |\n", 317 | "\n", 318 | "\n", 319 | "**5. 스타크래프트의 세계관:**\n", 320 | "\n", 321 | "* **다양한 배경 & 역사**: 세 가지 종족 간의 전쟁과 이를 배경으로 한 이야기들이 있습니다.\n", 322 | "* **자연스러운 대결**: 다른 종족들과의 격렬한 전투는 게임을 더욱 매력적인 경험으로 만들어줍니다.\n", 323 | "\n", 324 | "\n", 325 | "\n", 326 | "**6. 스타크래프트는:**\n", 327 | "\n", 328 | "* **RTS 장르의 선두주자:** 다양한 플레이어들을 위한 흥미로운 게임 경험을 제공합니다.\n", 329 | "* **강력한 전략 게임:** 여러 가지 요소를 조절하고 전략적으로 진행해야 하는 게임입니다.\n", 330 | "\n", 331 | "\n", 332 | "**7. 추가 정보**:\n", 333 | "\n", 334 | "* 스타크래프트의 세계관은 매우 풍부하여 다양한 이야기를 통해 만성적인 경험을 제공합니다.\n", 335 | "* 끊임없이 개발되는 스타크래프트는 장기적 관점에서도 게임의 지속 가능성이 높습니다.\n", 336 | "\n", 337 | "\n", 338 | "\n" 339 | ], 340 | "text/plain": [ 341 | "" 342 | ] 343 | }, 344 | "execution_count": 35, 345 | "metadata": {}, 346 | "output_type": "execute_result" 347 | } 348 | ], 349 | "source": [ 350 | "response = llm.predict(f\"질문: {query}\\n관련 문서: {', '.join(related_docs)}\\n응답:\")\n", 351 | "Markdown(response)" 352 | ] 353 | }, 354 | { 355 | "cell_type": "markdown", 356 | "metadata": {}, 357 | "source": [ 358 | "### 윷놀이 관련 질의" 359 | ] 360 | }, 361 | { 362 | "cell_type": "code", 363 | "execution_count": 36, 364 | "metadata": {}, 365 | "outputs": [ 366 | { 367 | "name": "stdout", 368 | "output_type": "stream", 369 | "text": [ 370 | "질문: 윷놀이에서 상대방 말을 잡으면 어떻게 돼?\n", 371 | "관련 문서: ['\\n윷놀이 규칙\\n1. 준비물\\n\\n윷: 앞뒤가 다른 네 개의 막대.\\n윷판: 원형 모양의 판, 중앙으로 가는 지름길이 있습니다.\\n말: 각 팀이 사용할 말 4개.\\n2. 플레이어\\n\\n최소 2명에서 4명까지 팀을 이루어 플레이합니다.\\n3. 윷 던지기 윷은 네 개의 막대로 구성되어 있으며, 던진 결과에 따라 다음과 같은 점수를 얻습니다:\\n\\n도: 1칸 이동 (1개만 뒤집힘)\\n개: 2칸 이동 (2개 뒤집힘)\\n걸: 3칸 이동 (3개 뒤집힘)\\n윷: 4칸 이동 (4개 모두 뒤집힘)\\n모: 5칸 이동 (모두 안 뒤집힘)\\n4. 말 이동\\n\\n윷이나 모가 나오면 한 번 더 던질 수 있습니다.\\n말을 이동시키며, 자신의 말 4개가 모두 완주하면 승리합니다.\\n5. 말 업기\\n\\n같은 팀의 말이 한 칸에 모이면 말 업기가 가능합니다. 업힌 말은 함께 이동합니다.\\n6. 잡기\\n\\n상대방의 말을 잡으면, 상대방 말은 시작점으로 돌아갑니다. 잡은 플레이어는 한 번 더 윷을 던집니다.\\n7. 승리 조건\\n\\n자신의 말 4개를 모두 완주시키면 승리합니다.\\n특별 규칙\\n지름길: 중앙으로 가는 지름길을 통해 빠르게 이동할 수 있습니다.\\n말의 이동 선택: 윷을 던질 때, 여러 개의 말 중 어느 말이 이동할지 선택할 수 있습니다.\\n윷놀이는 간단하면서도 전략적인 게임으로, 운과 실력을 모두 요구하는 한국 전통 놀이입니다.', '\\n제기차기는 한국의 전통 놀이로, 주로 어린이들이 즐기는 활동입니다. 제기차기의 기본 규칙은 다음과 같습니다:\\n\\n제기 만들기: 제기는 주로 종이나 천으로 만들어진 둥글고 평평한 물체입니다. 흔히 종이로 만든 제기를 사용하며, 발 아래에 적당한 무게가 있는 경우가 많습니다.\\n\\n차기: 플레이어는 제기를 발로 차서 공중으로 띄웁니다. 제기가 땅에 떨어지기 전에 다시 차서 계속 공중에 띄워야 합니다.\\n\\n점수 시스템: 제기를 공중에 얼마나 많이 띄우는지에 따라 점수를 매깁니다. 특정 횟수 이상을 차면 점수를 부여할 수 있습니다.\\n\\n대결: 여러 명이 함께 제기차기를 하며, 서로의 제기를 방해하거나 더 높은 점수를 내는 방식으로 대결할 수 있습니다.\\n\\n규칙 변형: 지역이나 그룹에 따라 제기차기 방식이나 규칙이 다를 수 있으며, 다양한 변형 규칙이 존재합니다.\\n\\n제기차기는 신체 운동과 협동심을 기르는 데 도움이 되는 놀이입니다!\\n']\n" 372 | ] 373 | } 374 | ], 375 | "source": [ 376 | "query = \"윷놀이에서 상대방 말을 잡으면 어떻게 돼?\"\n", 377 | "related_docs = search_related_docs(embedding_model, query, documents)\n", 378 | "print(\"질문:\", query)\n", 379 | "print(\"관련 문서:\", related_docs)" 380 | ] 381 | }, 382 | { 383 | "cell_type": "code", 384 | "execution_count": 37, 385 | "metadata": {}, 386 | "outputs": [ 387 | { 388 | "data": { 389 | "text/markdown": [ 390 | "윷놀이는 상대방 말을 잡으면 **상대방의 말은 시작점으로 돌아갑니다.** 그리고 잡은 플레이어는 한 번 더 윷을 던집니다. \n", 391 | "\n", 392 | "\n", 393 | "\n", 394 | "\n", 395 | "**추가 정보:** \n", 396 | "\n", 397 | "\n", 398 | "* 잡기는 윷놀이에서 중요한 요소입니다.\n", 399 | "* 잡기를 통해 상대방의 말을 획득하여 점수를 얻는 방법을 학습하고 실력을 향상할 수 있습니다. \n", 400 | "\n", 401 | "\n", 402 | "\n" 403 | ], 404 | "text/plain": [ 405 | "" 406 | ] 407 | }, 408 | "execution_count": 37, 409 | "metadata": {}, 410 | "output_type": "execute_result" 411 | } 412 | ], 413 | "source": [ 414 | "response = llm.predict(f\"질문: {query}\\n관련 문서: {', '.join(related_docs)}\\n응답:\")\n", 415 | "Markdown(response)" 416 | ] 417 | } 418 | ], 419 | "metadata": { 420 | "kernelspec": { 421 | "display_name": "base", 422 | "language": "python", 423 | "name": "python3" 424 | }, 425 | "language_info": { 426 | "codemirror_mode": { 427 | "name": "ipython", 428 | "version": 3 429 | }, 430 | "file_extension": ".py", 431 | "mimetype": "text/x-python", 432 | "name": "python", 433 | "nbconvert_exporter": "python", 434 | "pygments_lexer": "ipython3", 435 | "version": "3.12.4" 436 | } 437 | }, 438 | "nbformat": 4, 439 | "nbformat_minor": 2 440 | } 441 | -------------------------------------------------------------------------------- /OpenAI/OpenAI_API_call.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "provenance": [], 7 | "authorship_tag": "ABX9TyMVpIolARZBJitDhhsBoEZO", 8 | "include_colab_link": true 9 | }, 10 | "kernelspec": { 11 | "name": "python3", 12 | "display_name": "Python 3" 13 | }, 14 | "language_info": { 15 | "name": "python" 16 | } 17 | }, 18 | "cells": [ 19 | { 20 | "cell_type": "markdown", 21 | "metadata": { 22 | "id": "view-in-github", 23 | "colab_type": "text" 24 | }, 25 | "source": [ 26 | "\"Open" 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "source": [ 32 | "# **OpenAI API Call**\n", 33 | "\n", 34 | "**OpenAI**의 **Chat API**를 호출해 보는 간단한 실습 코드입니다." 35 | ], 36 | "metadata": { 37 | "id": "IGSKG41yelP_" 38 | } 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "source": [ 43 | "## **1. 환경 세팅**\n", 44 | "- OpenAI 라이브러리 설치\n", 45 | "- API Key 입력" 46 | ], 47 | "metadata": { 48 | "id": "cml80vUosW3m" 49 | } 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": null, 54 | "metadata": { 55 | "colab": { 56 | "base_uri": "https://localhost:8080/" 57 | }, 58 | "id": "Lg9EMEGXsK09", 59 | "outputId": "863c5e04-4eff-4e53-94a2-1e689c5a280b" 60 | }, 61 | "outputs": [ 62 | { 63 | "output_type": "stream", 64 | "name": "stdout", 65 | "text": [ 66 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m374.1/374.1 kB\u001b[0m \u001b[31m3.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 67 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m76.4/76.4 kB\u001b[0m \u001b[31m3.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 68 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m77.9/77.9 kB\u001b[0m \u001b[31m3.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 69 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m318.9/318.9 kB\u001b[0m \u001b[31m14.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 70 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m58.3/58.3 kB\u001b[0m \u001b[31m723.7 kB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 71 | "\u001b[?25h" 72 | ] 73 | } 74 | ], 75 | "source": [ 76 | "!pip -q install openai" 77 | ] 78 | }, 79 | { 80 | "cell_type": "code", 81 | "source": [ 82 | "from openai import OpenAI\n", 83 | "import os\n", 84 | "from getpass import getpass\n", 85 | "\n", 86 | "# Colab에 API 키를 안전하게 입력받기\n", 87 | "api_key = getpass(\"OpenAI API 키를 입력하세요: \")\n", 88 | "\n", 89 | "# API 키를 환경 변수에 저장\n", 90 | "os.environ['OPENAI_API_KEY'] = api_key" 91 | ], 92 | "metadata": { 93 | "id": "QmIPe8Kvsjav" 94 | }, 95 | "execution_count": null, 96 | "outputs": [] 97 | }, 98 | { 99 | "cell_type": "markdown", 100 | "source": [ 101 | "## **2. OpenAI API 호출 함수**\n", 102 | "- model, message, temperatue, max_tokens를 입력받음" 103 | ], 104 | "metadata": { 105 | "id": "I_Z8rtgr0KGV" 106 | } 107 | }, 108 | { 109 | "cell_type": "code", 110 | "source": [ 111 | "def create_chat_completion(system_input, user_input, model=\"gpt-4o-mini\", temperature=1.15, max_tokens=150):\n", 112 | " try:\n", 113 | " # 메시지 목록을 자동으로 생성해요\n", 114 | " messages = [\n", 115 | " {\"role\": \"system\", \"content\": system_input},\n", 116 | " {\"role\": \"user\", \"content\": user_input}\n", 117 | " ]\n", 118 | "\n", 119 | " response = OpenAI().chat.completions.create(\n", 120 | " model=model,\n", 121 | " messages=messages,\n", 122 | " temperature=temperature,\n", 123 | " max_tokens=max_tokens # 최대 토큰 수를 지정해요\n", 124 | " )\n", 125 | " # 생성된 응답을 반환해요\n", 126 | " return response\n", 127 | " except Exception as e:\n", 128 | " return f\"Error: {str(e)}\"\n" 129 | ], 130 | "metadata": { 131 | "id": "mhT4Uf8-sWj1" 132 | }, 133 | "execution_count": null, 134 | "outputs": [] 135 | }, 136 | { 137 | "cell_type": "code", 138 | "source": [ 139 | "# 메시지 입력\n", 140 | "system_input = \"넌 AI 전문 강사아. AI, 개발에 관련된 질문에만 친절하고 간략하게 답변해줘\"\n", 141 | "user_input = \"LLM으로 무엇을 할 수 있는지 설명해줘.\"\n", 142 | "\n", 143 | "# API 호출 및 결과 출력\n", 144 | "responses = create_chat_completion(system_input, user_input)\n", 145 | "responses" 146 | ], 147 | "metadata": { 148 | "colab": { 149 | "base_uri": "https://localhost:8080/" 150 | }, 151 | "id": "T_hic1hmsWhj", 152 | "outputId": "327e7dff-d2a2-430c-d945-1fb8ab370717" 153 | }, 154 | "execution_count": null, 155 | "outputs": [ 156 | { 157 | "output_type": "execute_result", 158 | "data": { 159 | "text/plain": [ 160 | "ChatCompletion(id='chatcmpl-A7eyRHqCz0wULxRMJ63iq2NrG8Swi', choices=[Choice(finish_reason='length', index=0, logprobs=None, message=ChatCompletionMessage(content='LLM(대형 언어 모델)은 다음과 같은 다양한 용도로 활용할 수 있습니다:\\n\\n1. **텍스트 생성**: 이야기, 기사, 시 등 다양한 유형의 글을 생성할 수 있습니다.\\n2. **질문 답변**: 특정 주제에 대한 질문에 대해 신속하게 답변할 수 있습니다.\\n3. **언어 번역**: 여러 언어 간의 번역을 지원합니다.\\n4. **대화형 인터페이스**: 챗봇 및 가상 비서와 같은 애플리케이션에 통합되어 사용자와 대화할 수 있습니다.\\n5. **텍스트 요약**: 긴 문서나 기사를 간결하게 요약합니다', refusal=None, role='assistant', function_call=None, tool_calls=None))], created=1726389163, model='gpt-4o-mini-2024-07-18', object='chat.completion', service_tier=None, system_fingerprint='fp_483d39d857', usage=CompletionUsage(completion_tokens=150, prompt_tokens=51, total_tokens=201, completion_tokens_details=CompletionTokensDetails(reasoning_tokens=0)))" 161 | ] 162 | }, 163 | "metadata": {}, 164 | "execution_count": 30 165 | } 166 | ] 167 | }, 168 | { 169 | "cell_type": "code", 170 | "source": [ 171 | "responses.choices[0].message.content" 172 | ], 173 | "metadata": { 174 | "colab": { 175 | "base_uri": "https://localhost:8080/", 176 | "height": 72 177 | }, 178 | "id": "ZtbfnGbJsWUS", 179 | "outputId": "27c735da-42b9-4bfe-e56f-300f30ac9aae" 180 | }, 181 | "execution_count": null, 182 | "outputs": [ 183 | { 184 | "output_type": "execute_result", 185 | "data": { 186 | "text/plain": [ 187 | "'LLM(대형 언어 모델)은 다음과 같은 다양한 용도로 활용할 수 있습니다:\\n\\n1. **텍스트 생성**: 이야기, 기사, 시 등 다양한 유형의 글을 생성할 수 있습니다.\\n2. **질문 답변**: 특정 주제에 대한 질문에 대해 신속하게 답변할 수 있습니다.\\n3. **언어 번역**: 여러 언어 간의 번역을 지원합니다.\\n4. **대화형 인터페이스**: 챗봇 및 가상 비서와 같은 애플리케이션에 통합되어 사용자와 대화할 수 있습니다.\\n5. **텍스트 요약**: 긴 문서나 기사를 간결하게 요약합니다'" 188 | ], 189 | "application/vnd.google.colaboratory.intrinsic+json": { 190 | "type": "string" 191 | } 192 | }, 193 | "metadata": {}, 194 | "execution_count": 32 195 | } 196 | ] 197 | } 198 | ] 199 | } -------------------------------------------------------------------------------- /OpenAI/OpenAI_RAG_Llama_index.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "provenance": [], 7 | "authorship_tag": "ABX9TyMubx/7mnlQDfzIK11SZY30", 8 | "include_colab_link": true 9 | }, 10 | "kernelspec": { 11 | "name": "python3", 12 | "display_name": "Python 3" 13 | }, 14 | "language_info": { 15 | "name": "python" 16 | } 17 | }, 18 | "cells": [ 19 | { 20 | "cell_type": "markdown", 21 | "metadata": { 22 | "id": "view-in-github", 23 | "colab_type": "text" 24 | }, 25 | "source": [ 26 | "\"Open" 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "source": [ 32 | "# **OpenAI와 Llama-index를 이용한 RAG 실습**\n", 33 | "\n", 34 | "**OpenAI**와 **Llama-index**를 이용한, 조금 더 다양한 기능의 **RAG** 기능을 구현해보는 실습 코드입니다." 35 | ], 36 | "metadata": { 37 | "id": "IgzEw-9FeGka" 38 | } 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "source": [ 43 | "## **1. 환경 세팅**\n", 44 | "- 필요 라이브러리 설치\n", 45 | "- API Key 입력\n", 46 | "- 구글 드라이브 마운트" 47 | ], 48 | "metadata": { 49 | "id": "cml80vUosW3m" 50 | } 51 | }, 52 | { 53 | "cell_type": "code", 54 | "source": [ 55 | "!pip install -q openai llama-index llama-index-vector-stores-chroma" 56 | ], 57 | "metadata": { 58 | "id": "igHt8WP8SLxc", 59 | "colab": { 60 | "base_uri": "https://localhost:8080/" 61 | }, 62 | "outputId": "48572a96-b3f6-4c3b-ba48-4a8b0df8357f" 63 | }, 64 | "execution_count": null, 65 | "outputs": [ 66 | { 67 | "output_type": "stream", 68 | "name": "stdout", 69 | "text": [ 70 | "\u001b[?25l \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.0/67.3 kB\u001b[0m \u001b[31m?\u001b[0m eta \u001b[36m-:--:--\u001b[0m\r\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m67.3/67.3 kB\u001b[0m \u001b[31m3.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 71 | "\u001b[?25h Installing build dependencies ... \u001b[?25l\u001b[?25hdone\n", 72 | " Getting requirements to build wheel ... \u001b[?25l\u001b[?25hdone\n", 73 | " Preparing metadata (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n", 74 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m50.4/50.4 kB\u001b[0m \u001b[31m1.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 75 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m374.2/374.2 kB\u001b[0m \u001b[31m20.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 76 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m584.3/584.3 kB\u001b[0m \u001b[31m29.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 77 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2.4/2.4 MB\u001b[0m \u001b[31m65.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 78 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m76.4/76.4 kB\u001b[0m \u001b[31m4.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 79 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m77.9/77.9 kB\u001b[0m \u001b[31m5.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 80 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m318.9/318.9 kB\u001b[0m \u001b[31m20.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 81 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.6/1.6 MB\u001b[0m \u001b[31m55.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 82 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.2/1.2 MB\u001b[0m \u001b[31m52.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 83 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.5/1.5 MB\u001b[0m \u001b[31m51.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 84 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m273.8/273.8 kB\u001b[0m \u001b[31m14.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 85 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m94.0/94.0 kB\u001b[0m \u001b[31m4.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 86 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.7/1.7 MB\u001b[0m \u001b[31m42.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 87 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m187.4/187.4 kB\u001b[0m \u001b[31m11.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 88 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m67.6/67.6 kB\u001b[0m \u001b[31m4.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 89 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m13.2/13.2 MB\u001b[0m \u001b[31m84.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 90 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m64.0/64.0 kB\u001b[0m \u001b[31m3.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 91 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m52.5/52.5 kB\u001b[0m \u001b[31m3.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 92 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m149.7/149.7 kB\u001b[0m \u001b[31m9.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 93 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m110.5/110.5 kB\u001b[0m \u001b[31m6.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 94 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m141.9/141.9 kB\u001b[0m \u001b[31m8.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 95 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m54.3/54.3 kB\u001b[0m \u001b[31m3.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 96 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m295.8/295.8 kB\u001b[0m \u001b[31m16.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 97 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.1/1.1 MB\u001b[0m \u001b[31m41.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 98 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m62.8/62.8 kB\u001b[0m \u001b[31m4.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 99 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m58.3/58.3 kB\u001b[0m \u001b[31m3.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 100 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m341.4/341.4 kB\u001b[0m \u001b[31m21.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 101 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m49.3/49.3 kB\u001b[0m \u001b[31m2.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 102 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m71.4/71.4 kB\u001b[0m \u001b[31m4.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 103 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.4/3.4 MB\u001b[0m \u001b[31m77.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 104 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m425.7/425.7 kB\u001b[0m \u001b[31m22.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 105 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m157.3/157.3 kB\u001b[0m \u001b[31m10.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 106 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m46.0/46.0 kB\u001b[0m \u001b[31m2.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 107 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m86.8/86.8 kB\u001b[0m \u001b[31m6.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", 108 | "\u001b[?25h Building wheel for pypika (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n" 109 | ] 110 | } 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "source": [ 116 | "from getpass import getpass\n", 117 | "import os\n", 118 | "from openai import OpenAI\n", 119 | "import chromadb\n", 120 | "from chromadb.utils.embedding_functions import OpenAIEmbeddingFunction\n", 121 | "from IPython.display import Markdown, display\n", 122 | "from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, StorageContext, get_response_synthesizer\n", 123 | "from llama_index.core.retrievers import VectorIndexRetriever\n", 124 | "from llama_index.core.query_engine import RetrieverQueryEngine\n", 125 | "from llama_index.core.postprocessor import SimilarityPostprocessor\n", 126 | "from llama_index.vector_stores.chroma import ChromaVectorStore\n", 127 | "from llama_index.embeddings.openai import OpenAIEmbedding" 128 | ], 129 | "metadata": { 130 | "id": "71WAf2fMVKI4" 131 | }, 132 | "execution_count": null, 133 | "outputs": [] 134 | }, 135 | { 136 | "cell_type": "code", 137 | "source": [ 138 | "# Colab에 API 키를 안전하게 입력받기\n", 139 | "api_key = getpass(\"OpenAI API 키를 입력하세요: \")\n", 140 | "os.environ['OPENAI_API_KEY'] = api_key" 141 | ], 142 | "metadata": { 143 | "colab": { 144 | "base_uri": "https://localhost:8080/" 145 | }, 146 | "id": "QmIPe8Kvsjav", 147 | "outputId": "b0593bdc-a09f-4832-b125-9557113adbc8" 148 | }, 149 | "execution_count": null, 150 | "outputs": [ 151 | { 152 | "name": "stdout", 153 | "output_type": "stream", 154 | "text": [ 155 | "OpenAI API 키를 입력하세요: ··········\n" 156 | ] 157 | } 158 | ] 159 | }, 160 | { 161 | "cell_type": "code", 162 | "source": [ 163 | "from google.colab import drive\n", 164 | "drive.mount('/content/drive')" 165 | ], 166 | "metadata": { 167 | "colab": { 168 | "base_uri": "https://localhost:8080/" 169 | }, 170 | "id": "E87KkLX5VIIx", 171 | "outputId": "02f9d032-bb7a-4f43-ee1f-8f0ca716be5e" 172 | }, 173 | "execution_count": null, 174 | "outputs": [ 175 | { 176 | "output_type": "stream", 177 | "name": "stdout", 178 | "text": [ 179 | "Mounted at /content/drive\n" 180 | ] 181 | } 182 | ] 183 | }, 184 | { 185 | "cell_type": "markdown", 186 | "source": [ 187 | "## **2. 기본 예제**\n", 188 | "- 지정된 디렉토리에서 문서를 읽고, 이 문서들로부터 `VectorStoreIndex`를 생성하고, 이 인덱스를 쿼리 엔진으로 변환하여 입력된 쿼리와 관련된 정보를 검색하는 **가장 기본적인 예제**\n", 189 | "- 별도의 임베딩 모델이나 ChromaDB 같은 외부 벡터 저장소를 지정하지 않기 때문에 세밀한 조정은 불가능." 190 | ], 191 | "metadata": { 192 | "id": "uD6KA2m4W7Zu" 193 | } 194 | }, 195 | { 196 | "cell_type": "code", 197 | "source": [ 198 | "# RAG 참조 문서 디렉토리 지정 (각자 지정 필요)\n", 199 | "documents_dir = '/content/drive/MyDrive/코드 예제/LLM/ref_docs_2'" 200 | ], 201 | "metadata": { 202 | "id": "q-4tnJON5SFX" 203 | }, 204 | "execution_count": null, 205 | "outputs": [] 206 | }, 207 | { 208 | "cell_type": "code", 209 | "source": [ 210 | "# 문서를 읽어와 인덱스를 생성하고, 간단한 쿼리 엔진으로 검색하는 기본 예제입니다.\n", 211 | "documents = SimpleDirectoryReader(documents_dir).load_data()\n", 212 | "index = VectorStoreIndex.from_documents(documents)" 213 | ], 214 | "metadata": { 215 | "id": "OZsVKc9mS40S" 216 | }, 217 | "execution_count": null, 218 | "outputs": [] 219 | }, 220 | { 221 | "cell_type": "code", 222 | "source": [ 223 | "# 인덱스를 사용해 간단한 쿼리 엔진을 생성합니다.\n", 224 | "query_engine = index.as_query_engine()\n", 225 | "\n", 226 | "response = query_engine.query(\"KBO 한국 시리즈에서 우승하지 못한 팀을 알려줘\")\n", 227 | "display(Markdown(f\"{response}\"))" 228 | ], 229 | "metadata": { 230 | "colab": { 231 | "base_uri": "https://localhost:8080/" 232 | }, 233 | "id": "U2400DQuS_VM", 234 | "outputId": "505cbca1-cfd8-4ae8-c4e6-6cc5dae03a4c" 235 | }, 236 | "execution_count": null, 237 | "outputs": [ 238 | { 239 | "output_type": "stream", 240 | "name": "stdout", 241 | "text": [ 242 | "삼성 라이온즈\n" 243 | ] 244 | } 245 | ] 246 | }, 247 | { 248 | "cell_type": "markdown", 249 | "source": [ 250 | "## **3. ChromaDB와 OpenAI Embedding 모델 사용 예제**\n", 251 | "\n", 252 | "- 벡터 저장소로 ChromaDB를 통합하고 `OpenAIEmbedding`을 사용하여 커스텀 임베딩 모델을 정의\n", 253 | "- 메모리 상에 ChromaDB 클라이언트와 컬렉션을 초기화하고, `ChromaVectorStore`를 설정하여 데이터를 저장한 후 해당 저장소와 임베딩 모델을 사용하여 인덱스를 생성\n", 254 | "- 기본 예제와 달리, **임베딩 모델**과 **벡터 저장소**를 명시적으로 설정하여 **검색 정확도를 높일 수 있는 방법**" 255 | ], 256 | "metadata": { 257 | "id": "H5Ku_r7MTF_O" 258 | } 259 | }, 260 | { 261 | "cell_type": "code", 262 | "source": [ 263 | "# ChromaDB 클라이언트를 메모리상에 생성하고 새로운 컬렉션을 만듭니다.\n", 264 | "chroma_client = chromadb.EphemeralClient() # 메모리 상에 저장 (세션 간 데이터 유지가 필요 없다면 이 옵션 사용)\n", 265 | "chroma_collection = chroma_client.create_collection(\"quickstart\") # 컬렉션 생성은 최초 1회만 실행합니다." 266 | ], 267 | "metadata": { 268 | "id": "vEpyDRf3THPv" 269 | }, 270 | "execution_count": null, 271 | "outputs": [] 272 | }, 273 | { 274 | "cell_type": "code", 275 | "source": [ 276 | "# OpenAI 임베딩 모델을 정의합니다. (필요에 따라 모델을 변경할 수 있습니다.)\n", 277 | "embed_model = OpenAIEmbedding(model=\"text-embedding-ada-002\")\n", 278 | "\n", 279 | "# 문서들을 지정된 디렉토리에서 불러옵니다.\n", 280 | "documents = SimpleDirectoryReader(documents_dir).load_data()\n", 281 | "\n", 282 | "# ChromaVectorStore를 설정하고 데이터를 저장합니다.\n", 283 | "vector_store = ChromaVectorStore(chroma_collection=chroma_collection)\n", 284 | "storage_context = StorageContext.from_defaults(vector_store=vector_store)\n", 285 | "\n", 286 | "# 문서들로부터 인덱스를 생성합니다. 이때 ChromaDB와 임베딩 모델을 사용합니다.\n", 287 | "index = VectorStoreIndex.from_documents(\n", 288 | " documents, storage_context=storage_context, embed_model=embed_model\n", 289 | ")" 290 | ], 291 | "metadata": { 292 | "id": "_ZEiL7wJwYd2" 293 | }, 294 | "execution_count": null, 295 | "outputs": [] 296 | }, 297 | { 298 | "cell_type": "code", 299 | "source": [ 300 | "# 쿼리 엔진을 사용하여 질문에 답변합니다.\n", 301 | "query_engine = index.as_query_engine()\n", 302 | "\n", 303 | "# 예시 쿼리: 한국 시리즈에서 우승하지 못한 팀을 알려줘\n", 304 | "response = query_engine.query(\"한국 시리즈에서 우승하지 못한 팀을 알려줘\")\n", 305 | "display(Markdown(f\"{response}\"))" 306 | ], 307 | "metadata": { 308 | "colab": { 309 | "base_uri": "https://localhost:8080/", 310 | "height": 46 311 | }, 312 | "id": "VIFycIgDwlaA", 313 | "outputId": "b4e35f0a-9412-4683-de4a-a7948804f91a" 314 | }, 315 | "execution_count": null, 316 | "outputs": [ 317 | { 318 | "output_type": "display_data", 319 | "data": { 320 | "text/plain": [ 321 | "" 322 | ], 323 | "text/markdown": "키움 히어로즈" 324 | }, 325 | "metadata": {} 326 | } 327 | ] 328 | }, 329 | { 330 | "cell_type": "markdown", 331 | "source": [ 332 | "## **4. 고급 검색 및 후처리 사용 예제**\n", 333 | "- 검색 프로세스에 대해 더 세밀한 제어를 제공하는 방법\n", 334 | "- `VectorIndexRetriever`를 설정하여 **`similarity_top_k`** 파라미터 조절\n", 335 | "- `get_response_synthesizer()`를 사용하여 검색된 문서와 쿼리를 합치는 합성기를 정의\n", 336 | "- `SimilarityPostprocessor`의 **`similarity_cutoff`** 로 결과 필터링\n", 337 | "\n", 338 | "- **`similarity_top_k`**\n", 339 | " - 유사한 문서의 개수를 조절\n", 340 | " - 값이 높으면 더 많은 문서를 검색하지만, 불필요한 정보가 포함될 수 있음\n", 341 | "- **`similarity_cutoff`**\n", 342 | " - 검색된 문서 중 유사도가 일정 수준 이상인 것만 포함\n", 343 | " - 값을 낮추면 더 많은 결과를 포함하지만, 정확도가 떨어질 수 있음" 344 | ], 345 | "metadata": { 346 | "id": "aJ9prQ-fTUcX" 347 | } 348 | }, 349 | { 350 | "cell_type": "code", 351 | "source": [ 352 | "# 리트리버를 설정합니다. 'similarity_top_k'로 유사한 문서의 개수를 조절할 수 있습니다.\n", 353 | "retriever = VectorIndexRetriever(\n", 354 | " index=index, # 기존에 생성한 인덱스를 불러옵니다.\n", 355 | " similarity_top_k=10, # 유사한 문서 최대 10개를 선택합니다.\n", 356 | ")\n", 357 | "\n", 358 | "# 검색된 문서와 쿼리를 합성해주는 합성기를 가져옵니다.\n", 359 | "response_synthesizer = get_response_synthesizer()\n", 360 | "\n", 361 | "# 쿼리 엔진을 생성합니다. 후처리 단계에서 'similarity_cutoff'를 설정하여 유사도가 낮은 결과를 필터링할 수 있습니다.\n", 362 | "query_engine = RetrieverQueryEngine(\n", 363 | " retriever=retriever,\n", 364 | " response_synthesizer=response_synthesizer,\n", 365 | " node_postprocessors=[SimilarityPostprocessor(similarity_cutoff=0.1)], # 유사도가 0.1 이하인 결과는 제외\n", 366 | ")" 367 | ], 368 | "metadata": { 369 | "id": "dFdUJrJBTJBQ" 370 | }, 371 | "execution_count": null, 372 | "outputs": [] 373 | }, 374 | { 375 | "cell_type": "code", 376 | "source": [ 377 | "response = query_engine.query(\"KBO에서 가장 유명한 사건 3개를 알려줘\")\n", 378 | "display(Markdown(f\"{response}\"))" 379 | ], 380 | "metadata": { 381 | "colab": { 382 | "base_uri": "https://localhost:8080/", 383 | "height": 64 384 | }, 385 | "id": "uPks9NsRXoT6", 386 | "outputId": "283facf2-8569-4dd7-b10d-b411f0e21f24" 387 | }, 388 | "execution_count": null, 389 | "outputs": [ 390 | { 391 | "output_type": "display_data", 392 | "data": { 393 | "text/plain": [ 394 | "" 395 | ], 396 | "text/markdown": "삼청태, 삼성의 대구 유니폼, 그리고 2023 월드 베이스볼 클래식에서의 이강철호의 3대회 연속 1라운드 탈락이 KBO에서 가장 유명한 사건 3개입니다." 397 | }, 398 | "metadata": {} 399 | } 400 | ] 401 | } 402 | ] 403 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LLM-Tutorials 2 | 3 | 누구나 쉽게 따라할 수 있는 다양한 LLM(Language Model) 관련 예제를 소개하고 실습할 수 있는 공간입니다. 4 | 5 | 점점 많은 예제를 추가할 예정이니 많은 관심 부탁드립니다 🤗 6 | 7 | ## 📌 OpenAI 8 | - [OpenAI_API_call](OpenAI/OpenAI_API_call.ipynb) [Colab] 9 | - OpenAI API를 사용해 보고 싶다면? 10 | - [OpenAI_RAG_ChatAPI](OpenAI/OpenAI_RAG_ChatAPI.ipynb) [Colab] 11 | - **Chat API**와 **ChromaDB**를 사용하여, 간단한 **RAG** 기능을 구현해보는 예제 12 | - [OpenAI_RAG_Llama_index](OpenAI/OpenAI_RAG_Llama_index.ipynb) [Colab] 13 | - **OpenAI**와 **Llama-index**를 이용한, 조금 더 다양한 기능의 **RAG** 기능을 구현해보는 예제 14 | - **ChromaDB**, **OpenAI Embedding 모델** 사용 15 | - 고급 검색 및 후처리 적용 (**`similarity_top_k`**, **`similarity_cutoff`** 사용) 16 |
17 | 18 | 19 | ## 📌 오픈소스 LLM 20 | ### ✅ Basic Chat 21 | - [huggingface_LLM_chat](Open-source_LLM/basic_chat/huggingface_LLM_chat.ipynb) [Colab] 22 | - Huggingface Open-source LLM으로 **기본적인 질의 응답** 기능을 구현하는 예제 23 | - [langchain_ollama_QnA](Open-source_LLM/basic_chat/langchain_ollama_QnA.ipynb) 24 | - Langchain과 Ollama를 이용하여 기본적인 **Q&A 시스템**을 구현하는 예제 (대화 내용 기억 X) 25 | - [langchain_ollama_chatbot](Open-source_LLM/basic_chat/langchain_ollama_chatbot.ipynb) 26 | - Langchain과 Ollama를 이용하여 **대화형 챗봇**을 구현하는 예제 (대화 내용 기억 O) 27 | - [langchain_ollama_prompting](Open-source_LLM/basic_chat/langchain_ollama_prompting.ipynb) 28 | - Langchain과 Ollama를 이용하여 기본적인 **프롬프트 엔니어링**을 구현하는 예제 29 | 30 | ### ✅ RAG 31 | - [llama-index_huggingface_RAG_basicce_llama-index_RAG_basic](Open-source_LLM/rag/llama-index_huggingface_RAG_basic.ipynb) [Colab] 32 | - llama-index와 **huggingface** LLM을 이용하여 **기본적인 RAG** 기능을 구현하는 예제 33 | - [llama-index_ollama_RAG_basic](Open-source_LLM/rag/llama-index_ollama_RAG_basic.ipynb) 34 | - llama-index와 **ollama** LLM을 이용하여 **기본적인 RAG** 기능을 구현하는 예제 35 |
36 | 37 | 38 | ## 📌 공부 자료 39 | - [LangChain 한국어 튜토리얼](https://github.com/teddylee777/langchain-kr) 40 | - Teddy Lee님이 운영하는 레포지토리로 다양한 랭체인 한국어 튜토리얼을 제공해요 (1.2k stars) 41 | - [Large Language Model Course](https://github.com/mlabonne/llm-course) 42 | - 다양한 LLM 공부 자료와 LLM Scientist, LLM Engineer 로드맵을 제공해요 (38.8k stars) 43 | - [Building A Generative AI Platform](https://huyenchip.com/2024/07/25/genai-platform.html) 44 | - LLM 플랫폼을 구축하는 과정에 대한 포괄적인 설명을 제공하는 포스트예요. 45 | - 이 포스트는 기업들이 생성적 AI 애플리케이션을 어떻게 배포하는지에 대한 공통된 아키텍처와 그 구성 요소들을 다루고 있어요. 46 | - 기본적인 구조에서 출발하여, 필요에 따라 'Enhance Context', 'Put in Guardrails', 'Add Model Router and Gateway', 'Reduce Latency with Cache'와 같은 컴포넌트들을 추가하는 방법을 설명해줘요. 47 | - [Unsloth AI Fine-tuning](https://huggingface.co/unsloth) 48 | - Colab 환경에서 Fine-tuning 예제를 제공하는 Unsloth AI 49 |
50 | 51 | 52 | ## 🙋🏻‍♂️ 추가 설명 53 | - 예제는 구글 코랩 환경과 로컬 주피터 노트북 환경으로 구성되어 있어요. 54 | - 로컬 주피터 노트북 환경의 경우 개발 환경 세팅(라이브러리 설치 등)가 필요합니다. 55 | - Google Colab 환경의 예제는 [Colab] 표기 56 | --------------------------------------------------------------------------------