├── .gitignore ├── README.md ├── data ├── Data.csv ├── Knowledge_Base_ru.csv ├── OutdoorClothingCatalog_1000.csv ├── PEP8.txt ├── clients.csv ├── orders.csv ├── pizza_orders.csv ├── pizzas.csv ├── pizzeria.db ├── prepared_dataset.csv ├── result.json └── train.csv ├── images ├── LangChain.webp ├── PromptEngineering_Visual_6.png ├── RAG.png ├── SelfConsistency.png ├── ag2.webp ├── ag_err.png ├── captcha.jpeg ├── chat.png ├── cheesecake.png ├── choice_api.jpeg ├── code.png ├── comperison_memors.png ├── doc_loaders.png ├── docl.jpg ├── dodo_gpt_bot.jpg ├── emb_mod.png ├── emb_models.png ├── embedds_openai.png ├── emotional_pressure.png ├── faq_examples.jpeg ├── few_shot_prompt.png ├── few_shot_semantic_search.png ├── fine_tune.webp ├── finetune_vs_rag.webp ├── gkp.png ├── gpu.png ├── instruct.png ├── lama_docs.webp ├── lamauns.png ├── license_filter.png ├── license_model.png ├── llamas.jpeg ├── llm_ledearboard.png ├── lora.jpeg ├── mcsft.png ├── memories_conv.png ├── micr.png ├── models-colorgrey.jpg ├── modelsize.png ├── moe_list.png ├── moe_menu.png ├── multi_filter.png ├── openai_logo.jpeg ├── pal.png ├── parrots.jpg ├── pixel_lama.webp ├── prompt_def.webp ├── prompt_engineering_visual.png ├── prompt_teq.webp ├── qa_flow.jpeg ├── quant_list.png ├── quant_menu.png ├── rag.webp ├── rag1.png ├── react_sch.png ├── retr.png ├── retriver.png ├── rob.png ├── rout_chain.jpeg ├── russian.png ├── self.webp ├── seq_chain.jpeg ├── simple_chain.webp ├── spaceship.png ├── sql_agent.png ├── summarization_use_case.png ├── text_spliting.webp ├── tot.png ├── unsloth.png ├── vdb.png ├── volcano.jpg ├── wind.png └── wind2.png ├── notebooks ├── M1_Welcome.ipynb ├── M2.1_Prompt_Engineering_intro.ipynb ├── M2.2_LangChain_Prompting.ipynb ├── M3_LangChain_Agents_intro.ipynb ├── M3_LangChain_Chains.ipynb ├── M3_LangChain_Memory.ipynb ├── M4_Agents.ipynb ├── M4_Basic_Advansic_Prompting.ipynb ├── M4_RAG.ipynb ├── M5_2_Dataset_prepare.ipynb ├── M5_2_FineTuning.ipynb ├── M5_Zoo.ipynb ├── M5_fine_tuning_llama-3-1_peft.ipynb ├── server.py └── utils.py ├── streamlit-project ├── README.md ├── app.py ├── app_v2.py ├── dockerfile └── requirements.txt ├── whisper_bot_project └── README.md └── workshop └── DataFest_Rag_Workshop.ipynb /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/#use-with-ide 110 | .pdm.toml 111 | 112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 113 | __pypackages__/ 114 | 115 | # Celery stuff 116 | celerybeat-schedule 117 | celerybeat.pid 118 | 119 | # SageMath parsed files 120 | *.sage.py 121 | 122 | # Environments 123 | .env 124 | .venv 125 | env/ 126 | venv/ 127 | ENV/ 128 | env.bak/ 129 | venv.bak/ 130 | 131 | # Spyder project settings 132 | .spyderproject 133 | .spyproject 134 | 135 | # Rope project settings 136 | .ropeproject 137 | 138 | # mkdocs documentation 139 | /site 140 | 141 | # mypy 142 | .mypy_cache/ 143 | .dmypy.json 144 | dmypy.json 145 | 146 | # Pyre type checker 147 | .pyre/ 148 | 149 | # pytype static type analyzer 150 | .pytype/ 151 | 152 | # Cython debug symbols 153 | cython_debug/ 154 | 155 | # PyCharm 156 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 157 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 158 | # and can be added to the global gitignore or merged into this file. For a more nuclear 159 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 160 | #.idea/ 161 | *.egg-info 162 | __pycache__ 163 | dist/ 164 | *.pyc 165 | .venv/ 166 | .python-version 167 | utils.cpython-39.pyc 168 | 169 | # Jupyter Notebook 170 | .ipynb_checkpoints 171 | 172 | # IPython 173 | profile_default/ 174 | ipython_config.py 175 | 176 | # Folders 177 | do_not_commit_this/ 178 | tmp_data/ 179 | wandb/ 180 | test/ 181 | catboost_info/ 182 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # COURSE: Large Language Models in practice 2 | Материалы по курсу 'Делаем свой AI-продукт на базе ChatGPT или других LLM моделей.' 3 | 4 | [TG-канал курса](https://t.me/big_llm_course) 5 | [Курс на Stepik](https://stepik.org/a/178846) 6 | 7 | # 1. 🚀 Вступление 8 | 9 | * 1.1 🏁 Как правильно входить в курс? 10 | * 1.2 📈 Общий подход и точки роста приложений с LLM 11 | * 1.3 🔑 API-ключ курса или от OpenAI? 12 | 13 | # 2. 🎵 Промптинг - объясни LLM, что тебе от неё надо! 14 | 15 | * 2.1 📝 Введение в Prompt Engineering 16 | * 2.2 👩‍🎨 Дизайн промптов в LangChain 17 | 18 | # 3. 🦜🔗 LangChain или причём тут попугаи? 19 | 20 | * 3.1 🧠 Память в LangChain 21 | * 3.2 🔗 Chains - собери свою цепь 22 | * 3.3 🕵️‍♂️ Агенты intro 23 | 24 | # 4. LLM и ваши данные | 🤖 + 🧠 = 🦞 25 | 26 | * 4.1 📤 RAG с вашими данными 27 | * 4.2 👨‍🔧👩‍🌾👷‍♂️ Собери свою банду агентов и завали босса 28 | * 4.3 Prompt Engineering - был basic, стал advansic 29 | 30 | # 5. Дообучение на своих данных | 🤖 + 💫 = 🚀 31 | 32 | * 5.1 🧩 Open Source модели на замену ChatGPT. 33 | * 5.2 🪗 Fine-tuning языковых моделей на своих данных. 34 | 35 | # 6. А не сделать ли нам свой LLM-проект уже сейчас?! 36 | 37 | * 6.1 🍕 Чат-бот заказчик и база знаний выдач 38 | * 6.2 🇺🇸 AI English Assistant 🤖 39 | * 6.3 👨‍🔧 Сдача проекта 40 | 41 | -------------------------------------------------------------------------------- /data/Data.csv: -------------------------------------------------------------------------------- 1 | Product,Review 2 | Queen Size Sheet Set,"I ordered a king size set. My only criticism would be that I wish seller would offer the king size set with 4 pillowcases. I separately ordered a two pack of pillowcases so I could have a total of four. When I saw the two packages, it looked like the color did not exactly match. Customer service was excellent about sending me two more pillowcases so I would have four that matched. Excellent! For the cost of these sheets, I am satisfied with the characteristics and coolness of the sheets." 3 | Waterproof Phone Pouch,"I loved the waterproof sac, although the opening was made of a hard plastic. I don’t know if that would break easily. But I couldn’t turn my phone on, once it was in the pouch." 4 | Luxury Air Mattress,"This mattress had a small hole in the top of it (took forever to find where it was), and the patches that they provide did not work, maybe because it's the top of the mattress where it's kind of like fabric and a patch won't stick. Maybe I got unlucky with a defective mattress, but where's quality assurance for this company? That flat out should not happen. Emphasis on flat. Cause that's what the mattress was. Seriously horrible experience, ruined my friend's stay with me. Then they make you ship it back instead of just providing a refund, which is also super annoying to pack up an air mattress and take it to the UPS store. This company is the worst, and this mattress is the worst." 5 | Pillows Insert,"This is the best throw pillow fillers on Amazon. I’ve tried several others, and they’re all cheap and flat no matter how much fluffing you do. Once you toss these in the dryer after you remove them from the vacuum sealed shipping material, they fluff up great" 6 | "Milk Frother Handheld 7 | "," I loved this product. But they only seem to last a few months. The company was great replacing the first one (the frother falls out of the handle and can't be fixed). The after 4 months my second one did the same. I only use the frother for coffee once a day. It's not overuse or abuse. I'm very disappointed and will look for another. As I understand they will only replace once. Anyway, if you have one good luck." 8 | "L'Or Espresso Café  9 | ","Je trouve le goût médiocre. La mousse ne tient pas, c'est bizarre. J'achète les mêmes dans le commerce et le goût est bien meilleur... 10 | Vieux lot ou contrefaçon !?" 11 | Hervidor de Agua Eléctrico,"Está lu bonita calienta muy rápido, es muy funcional, solo falta ver cuánto dura, solo llevo 3 días en funcionamiento." -------------------------------------------------------------------------------- /data/clients.csv: -------------------------------------------------------------------------------- 1 | id,name,age,address,phone 2 | 1,Виссарион Огарев,26,ул. Ордынка М. 1108,+7-943-980-0050 3 | 2,Гордей Брагин,38,ул. Коммунистическая 847,+7-928-427-6017 4 | 3,Лукьян Артёмов,26,ул. Лапина 1121,+7-956-078-2824 5 | 4,Никита Арановский,32,ул. Чоботовская 3-я 577,+7-912-979-7010 6 | 5,Якун Бабиков,36,Аллея Барабанная 886,+7-906-960-4302 7 | 6,Аркадий Прашкевич,38,Аллея Воронцовские Пруды 293,+7-942-907-0964 8 | 7,Харитон Гиляровский,64,ул. Дмитрия Ульянова 841,+7-906-408-2562 9 | 8,Евдоким Пестов,63,Аллея Медиков 653,+7-935-048-2074 10 | 9,Ждан Белых,46,ул. Зубовская 1232,+7-959-459-1297 11 | 10,Ермолай Владимиров,45,ул. Трехгорный Вал 404,+7-980-085-7701 12 | 11,Виталий Якимов,23,Аллея Тамбовская 283,+7-952-141-9265 13 | 12,Юстин Беленький,19,Аллея Госпитальный Вал 327,+7-978-635-8125 14 | 13,Алексей Анненков,55,Аллея Терлецкая 678,+7-995-874-3516 15 | 14,Назар Пришвин,17,Аллея Съезжинская 1138,+7-979-426-6642 16 | 15,Фотий Громов,49,Аллея Хамовнический Вал 975,+7-944-930-1491 17 | 16,Павел Троцкий,53,ул. Кетчерская 1197,+7-971-014-2447 18 | 17,Платон Зябликов,35,ул. Просвещения 700,+7-945-146-8367 19 | 18,Зиновий Луппол,58,ул. Лазенки 7-я 1332,+7-995-272-7525 20 | 19,Акакий Богданов,39,ул. Лескова 1376,+7-979-165-3542 21 | 20,Трофим Мурманский,43,ул. Кабельная 4-я 538,+7-990-118-7077 22 | 21,Корнилий Чехов,34,ул. Стройковская 473,+7-956-007-1075 23 | 22,Фотий Слюньков,63,ул. Кантемировская 761,+7-923-597-0697 24 | 23,Никон Хемлин,38,Аллея Лужская 1311,+7-903-719-2665 25 | 24,Спиридон Кошелёв,41,Аллея Сальвадора Альенде 1243,+7-964-077-8436 26 | 25,Потап Моисеев,47,ул. Новохохловская 530,+7-982-163-8507 27 | 26,Юрий Кудряшов,22,ул. Саперная 290,+7-960-958-8269 28 | 27,Мирон Кругосветов,25,Аллея Михайловка 50,+7-996-036-5876 29 | 28,Протасий Люкин,44,ул. Стройковская 932,+7-997-785-7731 30 | 29,Юстин Левонов,23,Аллея Политехническая 36,+7-911-679-7098 31 | 30,Тимур Ремнёв,25,ул. Радищевская Верхн. 384,+7-970-467-1201 32 | 31,Венедикт Могила,17,ул. Выставочная 91,+7-986-577-7353 33 | 32,Созон Сахарнов,38,ул. Кочновская 1168,+7-910-482-7347 34 | 33,Акакий Кандель,38,ул. Защитников Неба 555,+7-949-188-2949 35 | 34,Емельян Мартытов,31,ул. Яузская 204,+7-956-721-2040 36 | 35,Сильвестр Порфирьев,55,Аллея Луганская 1036,+7-999-758-2602 37 | 36,Фирс Семёнов,53,Аллея Востряковская 1277,+7-980-182-8791 38 | 37,Самуил Кошелёв,20,Аллея Парковая 8-я 138,+7-911-731-7235 39 | 38,Пётр Витязев,38,Аллея Добровольческая 721,+7-905-963-0333 40 | 39,Исидор Елизарьев,59,ул. Каменщики М. 795,+7-987-138-6781 41 | 40,Артур Омельчук,17,Аллея Екатерининская Б. 601,+7-909-671-2805 42 | 41,Ким Евплов,40,ул. Абельмановская Застава 645,+7-940-784-3149 43 | 42,Ириней Булычев,37,Аллея Госпитальный Вал 733,+7-955-185-6009 44 | 43,Анфим Нетёсов,62,Аллея Чоботовская 2-я 529,+7-999-533-0282 45 | 44,Конон Крамаренко,26,Аллея Предтеченский Верхн. 1103,+7-949-022-0050 46 | 45,Герасим Шпанов,62,ул. Сивяков 489,+7-941-364-8804 47 | 46,Владислав Силин,25,Аллея Маршала Захарова 349,+7-958-375-5996 48 | 47,Пахомий Демидов,40,Аллея Холмогорская 1264,+7-970-648-5951 49 | 48,Корнилий Васечкин,21,Аллея Милашенкова 1356,+7-900-834-7351 50 | 49,Добрыня Арбитман,37,ул. Коммунистическая 463,+7-985-184-7222 51 | 50,Леонтий Семенов,19,Аллея Новые Черемушки 32а 452,+7-925-214-3886 52 | 51,Климент Брагин,22,ул. Даниловский Вал 360,+7-957-748-4543 53 | 52,Прокопий Филимонихин,56,ул. Введенского 106,+7-950-501-1237 54 | 53,Виссарион Пименов,59,ул. Черногрязская 2-я 855,+7-947-552-0384 55 | 54,Константин Лепёхин,59,Аллея Лизы Чайкиной 1256,+7-963-456-5370 56 | 55,Тихон Бобков,17,Аллея Буракова 567,+7-988-115-3020 57 | 56,Демьян Ремизов,40,ул. Синичкина 2-я 874,+7-977-314-4222 58 | 57,Прохор Сычев,53,ул. Студеная 740,+7-937-154-6982 59 | 58,Богдан Яковлев,28,Аллея Можайский Вал 820,+7-998-924-2001 60 | 59,Анатолий Агутин,47,ул. Верхние Поля 83,+7-958-869-2083 61 | 60,Харитон Крылов,24,ул. Причальная 1349,+7-922-195-2527 62 | 61,Игнатий Басинский,23,Аллея Энергетическая 953,+7-974-645-9396 63 | 62,Леонид Ненароков,49,ул. Амурская 1048,+7-942-174-4804 64 | 63,Варфоломей Орлов,26,ул. Оленая 244,+7-903-272-4171 65 | 64,Мстислав Белов,61,Аллея Садовая-Триумфальная 477,+7-947-433-8768 66 | 65,Олег Светлов,23,ул. Савеловская 248,+7-948-425-5339 67 | 66,Святополк Киркиж,59,ул. Новозаводская 729,+7-994-984-5601 68 | 67,Андрей Бормор,29,ул. Вспольная 1239,+7-932-166-6395 69 | 68,Руслан Лазарев,34,ул. Филевская М. 372,+7-938-925-4722 70 | 69,Пётр Скоренко,23,ул. Старокаширское 959,+7-939-316-7218 71 | 70,Арсений Макаренко,48,ул. Нижняя 844,+7-917-103-4525 72 | 71,Лев Пишенко,18,ул. Педагогическая 1312,+7-965-894-1674 73 | 72,Лука Афремов,57,Аллея Курьяновская 4-я 317,+7-932-787-0795 74 | 73,Хрисанф Литаврин,38,ул. Щербаковская 1127,+7-983-036-2723 75 | 74,Авдей Рожков,63,ул. Синявинская 701,+7-991-316-7295 76 | 75,Ким Кривцов,21,Аллея Трехгорный Ср. 352,+7-993-394-3473 77 | 76,Серафим Пьянов,37,ул. Винницкая 168,+7-995-763-2520 78 | 77,Архипп Блохин,41,Аллея Городская 607,+7-902-328-0902 79 | 78,Денис Марков,19,Аллея Пестовская 68,+7-976-565-3416 80 | 79,Альвиан Гаммер,24,ул. Балтийская 313,+7-916-734-1617 81 | 80,Лев Немчинов,45,Аллея Мишина 1237,+7-928-556-9821 82 | 81,Альберт Корявин,33,ул. Вертолетчиков 559,+7-972-114-6482 83 | 82,Тихон Лощиц,51,ул. Соймоновская 229,+7-960-815-1546 84 | 83,Авдей Варченко,48,Аллея Маршала Голованова 478,+7-968-376-3253 85 | 84,Кирилл Юрский,41,ул. Розанова 694,+7-948-563-3830 86 | 85,Иван Михальченко,42,ул. Федоскинская 188,+7-943-332-0777 87 | 86,Константин Титов,33,ул. Мясницкая 1039,+7-926-333-0472 88 | 87,Гордей Скапидаров,54,ул. Вяземская 1186,+7-914-933-5584 89 | 88,Трофим Арефьев,39,Аллея Ватин Б. 807,+7-928-700-1038 90 | 89,Куприян Давыдов,48,ул. Измайловского Зверинца 1087,+7-983-217-9300 91 | 90,Лаврентий Байбородин,57,Аллея Джавахарлала Неру 1001,+7-946-647-3541 92 | 91,Федот Машкин,57,ул. Производственная 119,+7-919-139-7339 93 | 92,Федосей Вакулин,43,Аллея Колымажная 549,+7-986-660-1370 94 | 93,Мирон Нехлюдов,35,Аллея Лесные Пруды 1172,+7-960-932-3913 95 | 94,Николай Казакевич,37,ул. Алабушевская 760,+7-948-754-6688 96 | 95,Даниил Назарьев,65,Аллея Летниковская 964,+7-933-952-0117 97 | 96,Варлам Пушкин,65,Аллея Крупской 591,+7-966-352-4618 98 | 97,Олег Веденский,41,ул. Бартеневская 1387,+7-913-299-5879 99 | 98,Харитон Беляев,58,Аллея Карачаровское 507,+7-991-358-0566 100 | 99,Федосей Бессараб,49,ул. Академическая 1226,+7-935-169-5167 101 | -------------------------------------------------------------------------------- /data/orders.csv: -------------------------------------------------------------------------------- 1 | id,order_date,client_id,quantity,price 2 | 1,2023-05-01,1,1,750 3 | 2,2023-05-01,2,4,12000 4 | 3,2023-05-01,1,2,2750 5 | 4,2023-05-01,3,4,9500 6 | 5,2023-05-01,4,4,10000 7 | 6,2023-05-01,2,1,750 8 | 7,2023-05-02,1,2,3300 9 | 8,2023-05-02,5,4,10500 10 | 9,2023-05-02,5,3,5925 11 | 10,2023-05-02,6,3,4800 12 | 11,2023-05-03,6,1,625 13 | 12,2023-05-06,4,3,6450 14 | 13,2023-05-06,7,1,750 15 | 14,2023-05-06,3,1,750 16 | 15,2023-05-07,2,3,6375 17 | 16,2023-05-07,2,1,600 18 | 17,2023-05-07,1,1,600 19 | 18,2023-05-07,8,6,23850 20 | 19,2023-05-07,9,4,9500 21 | 20,2023-05-07,10,2,2500 22 | 21,2023-05-08,1,3,5250 23 | 22,2023-05-08,11,2,3000 24 | 23,2023-05-08,9,3,5925 25 | 24,2023-05-08,5,3,6300 26 | 25,2023-05-08,12,1,750 27 | 26,2023-05-08,3,5,14375 28 | 27,2023-05-09,13,1,625 29 | 28,2023-05-09,14,3,6375 30 | 29,2023-05-09,2,1,625 31 | 30,2023-05-09,15,5,18125 32 | 31,2023-05-09,16,4,10400 33 | 32,2023-05-10,16,1,625 34 | 33,2023-05-10,9,1,750 35 | 34,2023-05-13,1,3,5925 36 | 35,2023-05-13,7,1,900 37 | 36,2023-05-13,8,2,2500 38 | 37,2023-05-14,17,4,11100 39 | 38,2023-05-14,9,2,2000 40 | 39,2023-05-14,18,6,25650 41 | 40,2023-05-14,5,5,15750 42 | 41,2023-05-14,8,5,16875 43 | 42,2023-05-14,2,2,3000 44 | 43,2023-05-15,15,4,10100 45 | 44,2023-05-15,19,4,10500 46 | 45,2023-05-15,20,1,625 47 | 46,2023-05-15,14,3,6000 48 | 47,2023-05-15,4,6,24750 49 | 48,2023-05-15,9,4,11500 50 | 49,2023-05-15,15,3,5625 51 | 50,2023-05-16,21,1,750 52 | 51,2023-05-16,22,4,10000 53 | 52,2023-05-16,23,2,2800 54 | 53,2023-05-16,15,1,750 55 | 54,2023-05-16,1,5,16875 56 | 55,2023-05-17,8,1,500 57 | 56,2023-05-17,10,2,2000 58 | 57,2023-05-20,24,1,600 59 | 58,2023-05-20,14,2,2200 60 | 59,2023-05-20,23,3,6450 61 | 60,2023-05-21,25,2,2500 62 | 61,2023-05-21,4,3,7200 63 | 62,2023-05-21,26,3,4875 64 | 63,2023-05-21,7,5,16875 65 | 64,2023-05-21,1,5,17000 66 | 65,2023-05-21,27,1,625 67 | 66,2023-05-22,28,2,2500 68 | 67,2023-05-22,11,5,15000 69 | 68,2023-05-22,8,4,11000 70 | 69,2023-05-22,29,1,500 71 | 70,2023-05-22,30,4,10600 72 | 71,2023-05-22,31,6,23250 73 | 72,2023-05-22,24,2,2250 74 | 73,2023-05-23,17,3,5475 75 | 74,2023-05-23,8,4,11000 76 | 75,2023-05-23,32,4,11700 77 | 76,2023-05-23,33,4,10000 78 | 77,2023-05-23,16,1,625 79 | 78,2023-05-24,34,1,500 80 | 79,2023-05-24,24,2,2500 81 | 80,2023-05-27,11,1,625 82 | 81,2023-05-27,4,4,9900 83 | 82,2023-05-27,35,3,5625 84 | 83,2023-05-27,36,3,6375 85 | 84,2023-05-28,37,7,33425 86 | 85,2023-05-28,38,6,26400 87 | 86,2023-05-28,39,4,11100 88 | 87,2023-05-28,40,1,750 89 | 88,2023-05-28,41,2,3050 90 | 89,2023-05-28,18,1,750 91 | 90,2023-05-28,42,5,17625 92 | 91,2023-05-29,40,4,10500 93 | 92,2023-05-29,43,1,500 94 | 93,2023-05-29,26,6,22500 95 | 94,2023-05-29,1,6,23850 96 | 95,2023-05-29,44,5,15500 97 | 96,2023-05-29,45,3,5925 98 | 97,2023-05-29,46,1,750 99 | 98,2023-05-29,13,6,25650 100 | 99,2023-05-30,10,4,11600 101 | 100,2023-05-30,47,2,2500 102 | 101,2023-05-30,44,1,750 103 | 102,2023-05-30,39,3,6000 104 | 103,2023-05-30,31,1,750 105 | 104,2023-05-31,48,1,625 106 | 105,2023-05-31,49,1,500 107 | 106,2023-06-03,38,1,625 108 | 107,2023-06-03,50,4,11100 109 | 108,2023-06-03,51,3,6825 110 | 109,2023-06-03,25,2,2500 111 | 110,2023-06-04,35,2,2700 112 | 111,2023-06-04,52,4,9500 113 | 112,2023-06-04,44,4,9500 114 | 113,2023-06-04,17,2,3050 115 | 114,2023-06-04,24,7,36050 116 | 115,2023-06-04,53,7,31500 117 | 116,2023-06-04,54,2,2250 118 | 117,2023-06-05,28,6,23850 119 | 118,2023-06-05,55,7,32375 120 | 119,2023-06-05,50,3,5625 121 | 120,2023-06-05,2,3,6000 122 | 121,2023-06-05,11,5,15000 123 | 122,2023-06-05,9,8,41000 124 | 123,2023-06-05,56,1,500 125 | 124,2023-06-05,10,8,42000 126 | 125,2023-06-06,57,3,6075 127 | 126,2023-06-06,35,5,15000 128 | 127,2023-06-06,2,5,15000 129 | 128,2023-06-06,58,1,900 130 | 129,2023-06-06,59,4,11000 131 | 130,2023-06-06,60,2,3300 132 | 131,2023-06-07,49,2,2500 133 | 132,2023-06-07,55,1,900 134 | 133,2023-06-10,50,4,10500 135 | 134,2023-06-10,17,2,3000 136 | 135,2023-06-10,61,4,9900 137 | 136,2023-06-10,27,1,600 138 | 137,2023-06-11,53,5,17000 139 | 138,2023-06-11,62,5,16125 140 | 139,2023-06-11,52,5,15000 141 | 140,2023-06-11,63,3,6075 142 | 141,2023-06-11,64,7,35175 143 | 142,2023-06-11,40,5,14875 144 | 143,2023-06-11,65,6,26400 145 | 144,2023-06-12,23,8,42800 146 | 145,2023-06-12,66,8,41000 147 | 146,2023-06-12,53,8,41000 148 | 147,2023-06-12,67,6,23250 149 | 148,2023-06-12,68,3,6000 150 | 149,2023-06-12,3,5,16250 151 | 150,2023-06-12,69,3,4500 152 | 151,2023-06-12,70,4,9000 153 | 152,2023-06-13,17,4,11000 154 | 153,2023-06-13,28,3,5925 155 | 154,2023-06-13,67,6,24000 156 | 155,2023-06-13,64,5,14750 157 | 156,2023-06-13,71,6,23100 158 | 157,2023-06-13,72,5,17375 159 | 158,2023-06-14,45,2,2200 160 | 159,2023-06-14,11,2,2750 161 | 160,2023-06-17,50,4,8500 162 | 161,2023-06-17,39,2,2500 163 | 162,2023-06-17,56,3,6000 164 | 163,2023-06-17,73,2,3000 165 | 164,2023-06-18,74,5,17625 166 | 165,2023-06-18,75,8,36800 167 | 166,2023-06-18,76,8,40000 168 | 167,2023-06-18,30,6,23250 169 | 168,2023-06-18,77,2,3050 170 | 169,2023-06-18,78,5,15625 171 | 170,2023-06-18,3,4,10500 172 | 171,2023-06-18,50,7,33425 173 | 172,2023-06-19,79,8,42200 174 | 173,2023-06-19,40,7,33950 175 | 174,2023-06-19,80,7,30625 176 | 175,2023-06-19,40,3,5625 177 | 176,2023-06-19,21,8,44200 178 | 177,2023-06-19,65,3,6375 179 | 178,2023-06-19,8,7,30625 180 | 179,2023-06-19,22,8,38000 181 | 180,2023-06-19,81,9,58725 182 | 181,2023-06-20,3,5,15500 183 | 182,2023-06-20,70,6,21600 184 | 183,2023-06-20,82,2,3300 185 | 184,2023-06-20,83,1,750 186 | 185,2023-06-20,51,2,2250 187 | 186,2023-06-20,53,5,16750 188 | 187,2023-06-21,24,2,2500 189 | 188,2023-06-21,27,2,3300 190 | 189,2023-06-23,1,1,750 191 | 190,2023-06-24,42,4,10500 192 | 191,2023-06-24,23,3,6750 193 | 192,2023-06-24,51,3,6000 194 | 193,2023-06-24,84,2,2750 195 | 194,2023-06-25,85,8,44000 196 | 195,2023-06-25,86,2,3000 197 | 196,2023-06-25,87,7,32550 198 | 197,2023-06-25,88,1,625 199 | 198,2023-06-25,89,4,8000 200 | 199,2023-06-25,90,4,9400 201 | 200,2023-06-25,4,3,6750 202 | 201,2023-06-25,91,7,36050 203 | 202,2023-06-26,92,6,23250 204 | 203,2023-06-26,52,2,2000 205 | 204,2023-06-26,9,6,25500 206 | 205,2023-06-26,93,8,44200 207 | 206,2023-06-26,94,2,2750 208 | 207,2023-06-26,95,1,750 209 | 208,2023-06-26,47,2,2000 210 | 209,2023-06-26,15,4,11100 211 | 210,2023-06-26,96,8,44200 212 | 211,2023-06-27,73,4,12100 213 | 212,2023-06-27,88,1,750 214 | 213,2023-06-27,97,2,2500 215 | 214,2023-06-27,19,6,21600 216 | 215,2023-06-27,98,3,6375 217 | 216,2023-06-27,54,2,3000 218 | 217,2023-06-28,66,1,900 219 | 218,2023-06-28,99,2,2500 220 | 219,2023-06-30,33,1,625 221 | -------------------------------------------------------------------------------- /data/pizza_orders.csv: -------------------------------------------------------------------------------- 1 | order_id,pizza_id 2 | 1,15 3 | 2,56 4 | 2,22 5 | 2,37 6 | 2,87 7 | 3,103 8 | 3,98 9 | 4,121 10 | 4,113 11 | 4,22 12 | 4,109 13 | 5,40 14 | 5,73 15 | 5,38 16 | 5,97 17 | 6,25 18 | 7,106 19 | 7,135 20 | 8,44 21 | 8,85 22 | 8,35 23 | 8,39 24 | 9,135 25 | 9,40 26 | 9,11 27 | 10,29 28 | 10,78 29 | 10,1 30 | 11,41 31 | 12,92 32 | 12,119 33 | 12,2 34 | 13,79 35 | 14,38 36 | 15,138 37 | 15,25 38 | 15,134 39 | 16,78 40 | 17,23 41 | 18,20 42 | 18,135 43 | 18,33 44 | 18,104 45 | 18,116 46 | 18,105 47 | 19,95 48 | 19,65 49 | 19,136 50 | 19,64 51 | 20,109 52 | 20,147 53 | 21,27 54 | 21,76 55 | 21,57 56 | 22,118 57 | 22,51 58 | 23,131 59 | 23,53 60 | 23,134 61 | 24,93 62 | 24,60 63 | 24,37 64 | 25,67 65 | 26,8 66 | 26,139 67 | 26,47 68 | 26,30 69 | 26,138 70 | 27,21 71 | 28,85 72 | 28,56 73 | 28,135 74 | 29,107 75 | 30,72 76 | 30,144 77 | 30,71 78 | 30,61 79 | 30,110 80 | 31,75 81 | 31,4 82 | 31,74 83 | 31,30 84 | 32,136 85 | 33,135 86 | 34,3 87 | 34,132 88 | 34,24 89 | 35,86 90 | 36,6 91 | 36,96 92 | 37,86 93 | 37,132 94 | 37,138 95 | 37,141 96 | 38,29 97 | 38,108 98 | 39,44 99 | 39,111 100 | 39,85 101 | 39,59 102 | 39,19 103 | 39,101 104 | 40,144 105 | 40,81 106 | 40,84 107 | 40,108 108 | 40,101 109 | 41,111 110 | 41,60 111 | 41,133 112 | 41,41 113 | 41,48 114 | 42,93 115 | 42,110 116 | 43,124 117 | 43,30 118 | 43,97 119 | 43,94 120 | 44,44 121 | 44,109 122 | 44,62 123 | 44,146 124 | 45,140 125 | 46,48 126 | 46,149 127 | 46,120 128 | 47,127 129 | 47,66 130 | 47,24 131 | 47,126 132 | 47,42 133 | 47,52 134 | 48,91 135 | 48,14 136 | 48,32 137 | 48,71 138 | 49,28 139 | 49,10 140 | 49,40 141 | 50,105 142 | 51,66 143 | 51,104 144 | 51,127 145 | 51,96 146 | 52,94 147 | 52,50 148 | 53,7 149 | 54,84 150 | 54,131 151 | 54,135 152 | 54,116 153 | 54,102 154 | 55,129 155 | 56,83 156 | 56,31 157 | 57,20 158 | 58,31 159 | 58,23 160 | 59,119 161 | 59,84 162 | 59,147 163 | 60,19 164 | 60,40 165 | 61,67 166 | 61,124 167 | 61,7 168 | 62,69 169 | 62,94 170 | 62,108 171 | 63,51 172 | 63,79 173 | 63,21 174 | 63,65 175 | 63,59 176 | 64,77 177 | 64,74 178 | 64,41 179 | 64,1 180 | 64,87 181 | 65,40 182 | 66,140 183 | 66,74 184 | 67,136 185 | 67,57 186 | 67,41 187 | 67,27 188 | 67,146 189 | 68,142 190 | 68,43 191 | 68,72 192 | 68,127 193 | 69,113 194 | 70,100 195 | 70,26 196 | 70,95 197 | 70,81 198 | 71,128 199 | 71,38 200 | 71,10 201 | 71,73 202 | 71,46 203 | 71,48 204 | 72,123 205 | 72,1 206 | 73,3 207 | 73,14 208 | 73,75 209 | 74,73 210 | 74,4 211 | 74,48 212 | 74,32 213 | 75,119 214 | 75,9 215 | 75,26 216 | 75,136 217 | 76,56 218 | 76,122 219 | 76,94 220 | 76,4 221 | 77,89 222 | 78,97 223 | 79,146 224 | 79,77 225 | 80,140 226 | 81,144 227 | 81,37 228 | 81,5 229 | 81,141 230 | 82,64 231 | 82,107 232 | 82,141 233 | 83,58 234 | 83,14 235 | 83,49 236 | 84,64 237 | 84,150 238 | 84,97 239 | 84,87 240 | 84,94 241 | 84,102 242 | 84,106 243 | 85,106 244 | 85,107 245 | 85,44 246 | 85,41 247 | 85,15 248 | 85,4 249 | 86,97 250 | 86,17 251 | 86,18 252 | 86,145 253 | 87,52 254 | 88,87 255 | 88,19 256 | 89,142 257 | 90,62 258 | 90,48 259 | 90,76 260 | 90,72 261 | 90,101 262 | 91,92 263 | 91,28 264 | 91,118 265 | 91,138 266 | 92,90 267 | 93,146 268 | 93,147 269 | 93,21 270 | 93,51 271 | 93,41 272 | 93,68 273 | 94,64 274 | 94,4 275 | 94,23 276 | 94,147 277 | 94,118 278 | 94,69 279 | 95,103 280 | 95,122 281 | 95,63 282 | 95,37 283 | 95,95 284 | 96,89 285 | 96,75 286 | 96,63 287 | 97,91 288 | 98,21 289 | 98,2 290 | 98,119 291 | 98,63 292 | 98,105 293 | 98,146 294 | 99,18 295 | 99,68 296 | 99,98 297 | 99,86 298 | 100,140 299 | 100,40 300 | 101,110 301 | 102,132 302 | 102,62 303 | 102,131 304 | 103,4 305 | 104,12 306 | 105,83 307 | 106,48 308 | 107,139 309 | 107,103 310 | 107,45 311 | 107,108 312 | 108,62 313 | 108,50 314 | 108,140 315 | 109,8 316 | 109,43 317 | 110,102 318 | 110,16 319 | 111,130 320 | 111,140 321 | 111,99 322 | 111,127 323 | 112,73 324 | 112,59 325 | 112,115 326 | 112,107 327 | 113,64 328 | 113,124 329 | 114,4 330 | 114,6 331 | 114,51 332 | 114,119 333 | 114,44 334 | 114,46 335 | 114,63 336 | 115,117 337 | 115,122 338 | 115,121 339 | 115,23 340 | 115,5 341 | 115,145 342 | 115,128 343 | 116,14 344 | 116,39 345 | 117,117 346 | 117,50 347 | 117,131 348 | 117,83 349 | 117,16 350 | 117,75 351 | 118,71 352 | 118,85 353 | 118,81 354 | 118,51 355 | 118,117 356 | 118,135 357 | 118,6 358 | 119,17 359 | 119,146 360 | 119,25 361 | 120,19 362 | 120,28 363 | 120,30 364 | 121,143 365 | 121,112 366 | 121,24 367 | 121,76 368 | 121,10 369 | 122,133 370 | 122,149 371 | 122,147 372 | 122,138 373 | 122,140 374 | 122,10 375 | 122,139 376 | 122,58 377 | 123,10 378 | 124,67 379 | 124,71 380 | 124,107 381 | 124,115 382 | 124,41 383 | 124,21 384 | 124,33 385 | 124,65 386 | 125,68 387 | 125,87 388 | 125,143 389 | 126,1 390 | 126,133 391 | 126,108 392 | 126,38 393 | 126,82 394 | 127,108 395 | 127,64 396 | 127,104 397 | 127,71 398 | 127,82 399 | 128,101 400 | 129,43 401 | 129,88 402 | 129,55 403 | 129,51 404 | 130,52 405 | 130,106 406 | 131,90 407 | 131,142 408 | 132,86 409 | 133,27 410 | 133,74 411 | 133,33 412 | 133,148 413 | 134,126 414 | 134,28 415 | 135,147 416 | 135,138 417 | 135,23 418 | 135,73 419 | 136,3 420 | 137,87 421 | 137,62 422 | 137,34 423 | 137,6 424 | 137,10 425 | 138,129 426 | 138,79 427 | 138,4 428 | 138,48 429 | 138,3 430 | 139,144 431 | 139,79 432 | 139,108 433 | 139,94 434 | 139,136 435 | 140,90 436 | 140,64 437 | 140,26 438 | 141,12 439 | 141,60 440 | 141,137 441 | 141,50 442 | 141,42 443 | 141,89 444 | 141,32 445 | 142,2 446 | 142,143 447 | 142,76 448 | 142,141 449 | 142,78 450 | 143,17 451 | 143,101 452 | 143,138 453 | 143,24 454 | 143,33 455 | 143,43 456 | 144,72 457 | 144,65 458 | 144,14 459 | 144,15 460 | 144,144 461 | 144,16 462 | 144,96 463 | 144,59 464 | 145,96 465 | 145,114 466 | 145,104 467 | 145,12 468 | 145,53 469 | 145,128 470 | 145,106 471 | 145,120 472 | 146,74 473 | 146,73 474 | 146,57 475 | 146,143 476 | 146,105 477 | 146,113 478 | 146,34 479 | 146,30 480 | 147,136 481 | 147,142 482 | 147,80 483 | 147,127 484 | 147,2 485 | 147,5 486 | 148,18 487 | 148,35 488 | 148,104 489 | 149,115 490 | 149,129 491 | 149,91 492 | 149,25 493 | 149,7 494 | 150,127 495 | 150,31 496 | 150,29 497 | 151,127 498 | 151,115 499 | 151,92 500 | 151,44 501 | 152,19 502 | 152,61 503 | 152,58 504 | 152,64 505 | 153,75 506 | 153,59 507 | 153,13 508 | 154,43 509 | 154,49 510 | 154,21 511 | 154,69 512 | 154,12 513 | 154,42 514 | 155,78 515 | 155,20 516 | 155,99 517 | 155,88 518 | 155,51 519 | 156,74 520 | 156,53 521 | 156,122 522 | 156,72 523 | 156,12 524 | 156,52 525 | 157,30 526 | 157,37 527 | 157,25 528 | 157,57 529 | 157,71 530 | 158,3 531 | 158,8 532 | 159,71 533 | 159,107 534 | 160,133 535 | 160,104 536 | 160,125 537 | 160,27 538 | 161,61 539 | 161,81 540 | 162,98 541 | 162,73 542 | 162,43 543 | 163,15 544 | 163,79 545 | 164,70 546 | 164,32 547 | 164,50 548 | 164,27 549 | 164,62 550 | 165,37 551 | 165,54 552 | 165,31 553 | 165,99 554 | 165,30 555 | 165,38 556 | 165,127 557 | 165,141 558 | 166,138 559 | 166,95 560 | 166,85 561 | 166,94 562 | 166,96 563 | 166,31 564 | 166,55 565 | 166,62 566 | 167,83 567 | 167,10 568 | 167,136 569 | 167,150 570 | 167,34 571 | 167,101 572 | 168,106 573 | 168,132 574 | 169,122 575 | 169,35 576 | 169,94 577 | 169,137 578 | 169,89 579 | 170,85 580 | 170,25 581 | 170,72 582 | 170,83 583 | 171,136 584 | 171,33 585 | 171,95 586 | 171,140 587 | 171,58 588 | 171,133 589 | 171,119 590 | 172,1 591 | 172,97 592 | 172,62 593 | 172,5 594 | 172,106 595 | 172,27 596 | 172,118 597 | 172,58 598 | 173,62 599 | 173,20 600 | 173,17 601 | 173,61 602 | 173,105 603 | 173,14 604 | 173,103 605 | 174,130 606 | 174,73 607 | 174,128 608 | 174,104 609 | 174,4 610 | 174,42 611 | 174,10 612 | 175,80 613 | 175,94 614 | 175,100 615 | 176,29 616 | 176,150 617 | 176,145 618 | 176,119 619 | 176,49 620 | 176,6 621 | 176,73 622 | 176,52 623 | 177,34 624 | 177,21 625 | 177,24 626 | 178,51 627 | 178,149 628 | 178,57 629 | 178,92 630 | 178,31 631 | 178,5 632 | 178,9 633 | 179,127 634 | 179,143 635 | 179,19 636 | 179,35 637 | 179,115 638 | 179,43 639 | 179,81 640 | 179,144 641 | 180,131 642 | 180,71 643 | 180,61 644 | 180,2 645 | 180,26 646 | 180,33 647 | 180,17 648 | 180,72 649 | 180,120 650 | 181,7 651 | 181,5 652 | 181,37 653 | 181,82 654 | 181,95 655 | 182,121 656 | 182,53 657 | 182,12 658 | 182,138 659 | 182,95 660 | 182,62 661 | 183,28 662 | 183,86 663 | 184,67 664 | 185,30 665 | 185,143 666 | 186,110 667 | 186,44 668 | 186,53 669 | 186,60 670 | 186,29 671 | 187,5 672 | 187,144 673 | 188,45 674 | 188,126 675 | 189,52 676 | 190,108 677 | 190,128 678 | 190,112 679 | 190,111 680 | 191,102 681 | 191,86 682 | 191,150 683 | 192,35 684 | 192,111 685 | 192,94 686 | 193,46 687 | 193,40 688 | 194,112 689 | 194,123 690 | 194,56 691 | 194,38 692 | 194,93 693 | 194,43 694 | 194,132 695 | 194,9 696 | 195,87 697 | 195,23 698 | 196,31 699 | 196,66 700 | 196,77 701 | 196,47 702 | 196,34 703 | 196,106 704 | 196,125 705 | 197,73 706 | 198,90 707 | 198,143 708 | 198,81 709 | 198,39 710 | 199,54 711 | 199,97 712 | 199,23 713 | 199,7 714 | 200,55 715 | 200,4 716 | 200,18 717 | 201,141 718 | 201,135 719 | 201,91 720 | 201,34 721 | 201,89 722 | 201,103 723 | 201,145 724 | 202,146 725 | 202,62 726 | 202,135 727 | 202,8 728 | 202,18 729 | 202,30 730 | 203,76 731 | 203,83 732 | 204,22 733 | 204,135 734 | 204,59 735 | 204,109 736 | 204,46 737 | 204,33 738 | 205,21 739 | 205,24 740 | 205,26 741 | 205,57 742 | 205,83 743 | 205,25 744 | 205,62 745 | 205,8 746 | 206,140 747 | 206,22 748 | 207,33 749 | 208,114 750 | 208,29 751 | 209,22 752 | 209,141 753 | 209,83 754 | 209,45 755 | 210,113 756 | 210,140 757 | 210,13 758 | 210,40 759 | 210,124 760 | 210,144 761 | 210,20 762 | 210,26 763 | 211,106 764 | 211,24 765 | 211,135 766 | 211,89 767 | 212,61 768 | 213,27 769 | 213,100 770 | 214,125 771 | 214,128 772 | 214,146 773 | 214,75 774 | 214,5 775 | 214,24 776 | 215,67 777 | 215,141 778 | 215,110 779 | 216,105 780 | 216,52 781 | 217,106 782 | 218,85 783 | 218,84 784 | 219,120 785 | -------------------------------------------------------------------------------- /data/pizzas.csv: -------------------------------------------------------------------------------- 1 | id,type,name,size,price 2 | 1,Веган,Фермерская,S,500 3 | 2,Птица,Маргарита,L,750 4 | 3,Морепродукты,Фермерская,S,600 5 | 4,Мясо,С ананасами,L,750 6 | 5,Веган,Золотая рыбка,M,625 7 | 6,Птица,Золотая рыбка,S,500 8 | 7,Веган,Фермерская,L,750 9 | 8,Птица,4 сыра,S,500 10 | 9,Мясо,Золотая рыбка,S,500 11 | 10,Мясо,Крабы,S,500 12 | 11,Морепродукты,Фермерская,S,600 13 | 12,Мясо,Фермерская,M,625 14 | 13,Мясо,С ананасами,L,750 15 | 14,Веган,Маргарита,M,625 16 | 15,Морепродукты,Маргарита,M,750 17 | 16,Морепродукты,Фермерская,S,600 18 | 17,Веган,Крабы,M,625 19 | 18,Морепродукты,Фермерская,M,750 20 | 19,Мясо,Золотая рыбка,M,625 21 | 20,Морепродукты,Маргарита,S,600 22 | 21,Веган,4 сыра,M,625 23 | 22,Морепродукты,Золотая рыбка,M,750 24 | 23,Морепродукты,Ранч,S,600 25 | 24,Морепродукты,Фермерская,M,750 26 | 25,Птица,Фермерская,L,750 27 | 26,Морепродукты,Краб+Кальмар,L,900 28 | 27,Веган,Фермерская,S,500 29 | 28,Морепродукты,Краб+Кальмар,M,750 30 | 29,Птица,Крабы,S,500 31 | 30,Мясо,4 сыра,M,625 32 | 31,Птица,Фермерская,S,500 33 | 32,Птица,Фермерская,L,750 34 | 33,Морепродукты,С ананасами,M,750 35 | 34,Мясо,Ранч,L,750 36 | 35,Мясо,Маргарита,L,750 37 | 36,Мясо,Фермерская,M,625 38 | 37,Морепродукты,Ранч,S,600 39 | 38,Птица,4 сыра,L,750 40 | 39,Мясо,4 сыра,S,500 41 | 40,Веган,Фермерская,M,625 42 | 41,Мясо,4 сыра,M,625 43 | 42,Веган,Фермерская,M,625 44 | 43,Мясо,Фермерская,L,750 45 | 44,Веган,Крабы,L,750 46 | 45,Морепродукты,Маргарита,L,900 47 | 46,Веган,4 сыра,L,750 48 | 47,Мясо,Фермерская,S,500 49 | 48,Птица,Маргарита,M,625 50 | 49,Птица,Краб+Кальмар,L,750 51 | 50,Морепродукты,Золотая рыбка,L,900 52 | 51,Веган,Краб+Кальмар,L,750 53 | 52,Птица,Крабы,L,750 54 | 53,Морепродукты,Фермерская,S,600 55 | 54,Веган,Фермерская,S,500 56 | 55,Птица,Фермерская,L,750 57 | 56,Веган,Маргарита,L,750 58 | 57,Птица,4 сыра,L,750 59 | 58,Веган,Краб+Кальмар,L,750 60 | 59,Веган,С ананасами,M,625 61 | 60,Веган,Фермерская,L,750 62 | 61,Птица,4 сыра,L,750 63 | 62,Мясо,Маргарита,L,750 64 | 63,Мясо,Золотая рыбка,L,750 65 | 64,Веган,С ананасами,M,625 66 | 65,Птица,Краб+Кальмар,M,625 67 | 66,Веган,Краб+Кальмар,L,750 68 | 67,Мясо,Краб+Кальмар,L,750 69 | 68,Веган,4 сыра,M,625 70 | 69,Мясо,Ранч,M,625 71 | 70,Веган,Золотая рыбка,M,625 72 | 71,Морепродукты,Ранч,M,750 73 | 72,Мясо,Краб+Кальмар,L,750 74 | 73,Мясо,Фермерская,M,625 75 | 74,Веган,Фермерская,M,625 76 | 75,Морепродукты,Золотая рыбка,S,600 77 | 76,Веган,Золотая рыбка,S,500 78 | 77,Морепродукты,4 сыра,M,750 79 | 78,Морепродукты,Ранч,S,600 80 | 79,Морепродукты,Фермерская,M,750 81 | 80,Веган,Краб+Кальмар,M,625 82 | 81,Веган,Золотая рыбка,S,500 83 | 82,Мясо,Краб+Кальмар,M,625 84 | 83,Веган,4 сыра,S,500 85 | 84,Мясо,С ананасами,M,625 86 | 85,Птица,Краб+Кальмар,M,625 87 | 86,Морепродукты,4 сыра,L,900 88 | 87,Морепродукты,Краб+Кальмар,L,900 89 | 88,Мясо,Маргарита,S,500 90 | 89,Птица,Крабы,M,625 91 | 90,Птица,Фермерская,S,500 92 | 91,Морепродукты,Фермерская,M,750 93 | 92,Веган,Маргарита,S,500 94 | 93,Морепродукты,Маргарита,M,750 95 | 94,Мясо,Крабы,S,500 96 | 95,Мясо,Крабы,S,500 97 | 96,Морепродукты,Краб+Кальмар,M,750 98 | 97,Веган,Фермерская,S,500 99 | 98,Мясо,С ананасами,M,625 100 | 99,Веган,Фермерская,S,500 101 | 100,Морепродукты,С ананасами,M,750 102 | 101,Морепродукты,Маргарита,L,900 103 | 102,Веган,Крабы,L,750 104 | 103,Морепродукты,Краб+Кальмар,M,750 105 | 104,Птица,Крабы,S,500 106 | 105,Мясо,Крабы,L,750 107 | 106,Морепродукты,Краб+Кальмар,L,900 108 | 107,Веган,4 сыра,M,625 109 | 108,Веган,Ранч,S,500 110 | 109,Веган,4 сыра,M,625 111 | 110,Мясо,Фермерская,L,750 112 | 111,Птица,Маргарита,L,750 113 | 112,Морепродукты,Фермерская,M,750 114 | 113,Птица,Крабы,S,500 115 | 114,Птица,Маргарита,S,500 116 | 115,Веган,Ранч,S,500 117 | 116,Птица,С ананасами,M,625 118 | 117,Веган,С ананасами,L,750 119 | 118,Птица,4 сыра,L,750 120 | 119,Морепродукты,Краб+Кальмар,L,900 121 | 120,Мясо,Фермерская,M,625 122 | 121,Птица,Крабы,S,500 123 | 122,Веган,Золотая рыбка,S,500 124 | 123,Веган,Маргарита,M,625 125 | 124,Морепродукты,Золотая рыбка,L,900 126 | 125,Птица,Крабы,S,500 127 | 126,Мясо,4 сыра,L,750 128 | 127,Птица,С ананасами,S,500 129 | 128,Мясо,Крабы,M,625 130 | 129,Веган,С ананасами,S,500 131 | 130,Веган,Фермерская,L,750 132 | 131,Птица,Ранч,M,625 133 | 132,Птица,4 сыра,M,625 134 | 133,Птица,Золотая рыбка,M,625 135 | 134,Веган,С ананасами,L,750 136 | 135,Морепродукты,Краб+Кальмар,M,750 137 | 136,Веган,Краб+Кальмар,M,625 138 | 137,Птица,4 сыра,L,750 139 | 138,Птица,Маргарита,M,625 140 | 139,Веган,С ананасами,M,625 141 | 140,Веган,Ранч,M,625 142 | 141,Веган,Маргарита,M,625 143 | 142,Мясо,Фермерская,L,750 144 | 143,Мясо,4 сыра,S,500 145 | 144,Мясо,Золотая рыбка,M,625 146 | 145,Морепродукты,Золотая рыбка,L,900 147 | 146,Мясо,Фермерская,S,500 148 | 147,Птица,Фермерская,M,625 149 | 148,Морепродукты,Фермерская,M,750 150 | 149,Морепродукты,С ананасами,M,750 151 | 150,Морепродукты,Маргарита,S,600 152 | -------------------------------------------------------------------------------- /data/pizzeria.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/data/pizzeria.db -------------------------------------------------------------------------------- /data/train.csv: -------------------------------------------------------------------------------- 1 | "id","problem","answer" 2 | "229ee8","Let $k, l > 0$ be parameters. The parabola $y = kx^2 - 2kx + l$ intersects the line $y = 4$ at two points $A$ and $B$. These points are distance 6 apart. What is the sum of the squares of the distances from $A$ and $B$ to the origin?",52 3 | "246d26","Each of the three-digits numbers $111$ to $999$ is coloured blue or yellow in such a way that the sum of any two (not necessarily different) yellow numbers is equal to a blue number. What is the maximum possible number of yellow numbers there can be?",250 4 | "2fc4ad","Let the `sparkle' operation on positive integer $n$ consist of calculating the sum of the digits of $n$ and taking its factorial, e.g. the sparkle of 13 is $4! = 24$. A robot starts with a positive integer on a blackboard, then after each second for the rest of eternity, replaces the number on the board with its sparkle. For some `special' numbers, if they're the first number, then eventually every number that appears will be less than 6. How many such special numbers are there with at most 36 digits?",702 5 | "430b63","What is the minimum value of $5x^2+5y^2-8xy$ when $x$ and $y$ range over all real numbers such that $|x-2y| + |y-2x| = 40$?",800 6 | "5277ed","There exists a unique increasing geometric sequence of five 2-digit positive integers. What is their sum?",211 7 | "739bc9","For how many positive integers $m$ does the equation \[\vert \vert x-1 \vert -2 \vert=\frac{m}{100}\] have $4$ distinct solutions?",199 8 | "82e2a0","Suppose that we roll four 6-sided fair dice with faces numbered 1 to~6. Let $a/b$ be the probability that the highest roll is a 5, where $a$ and $b$ are relatively prime positive integers. Find $a + b$.",185 9 | "8ee6f3","The points $\left(x, y\right)$ satisfying $((\vert x + y \vert - 10)^2 + ( \vert x - y \vert - 10)^2)((\vert x \vert - 8)^2 + ( \vert y \vert - 8)^2) = 0$ enclose a convex polygon. What is the area of this convex polygon?",320 10 | "bedda4","Let $ABCD$ be a unit square. Let $P$ be the point on $AB$ such that $|AP| = 1/{20}$ and let $Q$ be the point on $AD$ such that $|AQ| = 1/{24}$. The lines $DP$ and $BQ$ divide the square into four regions. Find the ratio between the areas of the largest region and the smallest region.",480 11 | "d7e9c9","A function $f: \mathbb N \to \mathbb N$ satisfies the following two conditions for all positive integers $n$:$f(f(f(n)))=8n-7$ and $f(2n)=2f(n)+1$. Calculate $f(100)$.",199 12 | -------------------------------------------------------------------------------- /images/LangChain.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/LangChain.webp -------------------------------------------------------------------------------- /images/PromptEngineering_Visual_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/PromptEngineering_Visual_6.png -------------------------------------------------------------------------------- /images/RAG.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/RAG.png -------------------------------------------------------------------------------- /images/SelfConsistency.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/SelfConsistency.png -------------------------------------------------------------------------------- /images/ag2.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/ag2.webp -------------------------------------------------------------------------------- /images/ag_err.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/ag_err.png -------------------------------------------------------------------------------- /images/captcha.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/captcha.jpeg -------------------------------------------------------------------------------- /images/chat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/chat.png -------------------------------------------------------------------------------- /images/cheesecake.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/cheesecake.png -------------------------------------------------------------------------------- /images/choice_api.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/choice_api.jpeg -------------------------------------------------------------------------------- /images/code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/code.png -------------------------------------------------------------------------------- /images/comperison_memors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/comperison_memors.png -------------------------------------------------------------------------------- /images/doc_loaders.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/doc_loaders.png -------------------------------------------------------------------------------- /images/docl.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/docl.jpg -------------------------------------------------------------------------------- /images/dodo_gpt_bot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/dodo_gpt_bot.jpg -------------------------------------------------------------------------------- /images/emb_mod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/emb_mod.png -------------------------------------------------------------------------------- /images/emb_models.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/emb_models.png -------------------------------------------------------------------------------- /images/embedds_openai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/embedds_openai.png -------------------------------------------------------------------------------- /images/emotional_pressure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/emotional_pressure.png -------------------------------------------------------------------------------- /images/faq_examples.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/faq_examples.jpeg -------------------------------------------------------------------------------- /images/few_shot_prompt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/few_shot_prompt.png -------------------------------------------------------------------------------- /images/few_shot_semantic_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/few_shot_semantic_search.png -------------------------------------------------------------------------------- /images/fine_tune.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/fine_tune.webp -------------------------------------------------------------------------------- /images/finetune_vs_rag.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/finetune_vs_rag.webp -------------------------------------------------------------------------------- /images/gkp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/gkp.png -------------------------------------------------------------------------------- /images/gpu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/gpu.png -------------------------------------------------------------------------------- /images/instruct.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/instruct.png -------------------------------------------------------------------------------- /images/lama_docs.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/lama_docs.webp -------------------------------------------------------------------------------- /images/lamauns.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/lamauns.png -------------------------------------------------------------------------------- /images/license_filter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/license_filter.png -------------------------------------------------------------------------------- /images/license_model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/license_model.png -------------------------------------------------------------------------------- /images/llamas.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/llamas.jpeg -------------------------------------------------------------------------------- /images/llm_ledearboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/llm_ledearboard.png -------------------------------------------------------------------------------- /images/lora.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/lora.jpeg -------------------------------------------------------------------------------- /images/mcsft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/mcsft.png -------------------------------------------------------------------------------- /images/memories_conv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/memories_conv.png -------------------------------------------------------------------------------- /images/micr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/micr.png -------------------------------------------------------------------------------- /images/models-colorgrey.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/models-colorgrey.jpg -------------------------------------------------------------------------------- /images/modelsize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/modelsize.png -------------------------------------------------------------------------------- /images/moe_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/moe_list.png -------------------------------------------------------------------------------- /images/moe_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/moe_menu.png -------------------------------------------------------------------------------- /images/multi_filter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/multi_filter.png -------------------------------------------------------------------------------- /images/openai_logo.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/openai_logo.jpeg -------------------------------------------------------------------------------- /images/pal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/pal.png -------------------------------------------------------------------------------- /images/parrots.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/parrots.jpg -------------------------------------------------------------------------------- /images/pixel_lama.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/pixel_lama.webp -------------------------------------------------------------------------------- /images/prompt_def.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/prompt_def.webp -------------------------------------------------------------------------------- /images/prompt_engineering_visual.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/prompt_engineering_visual.png -------------------------------------------------------------------------------- /images/prompt_teq.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/prompt_teq.webp -------------------------------------------------------------------------------- /images/qa_flow.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/qa_flow.jpeg -------------------------------------------------------------------------------- /images/quant_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/quant_list.png -------------------------------------------------------------------------------- /images/quant_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/quant_menu.png -------------------------------------------------------------------------------- /images/rag.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/rag.webp -------------------------------------------------------------------------------- /images/rag1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/rag1.png -------------------------------------------------------------------------------- /images/react_sch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/react_sch.png -------------------------------------------------------------------------------- /images/retr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/retr.png -------------------------------------------------------------------------------- /images/retriver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/retriver.png -------------------------------------------------------------------------------- /images/rob.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/rob.png -------------------------------------------------------------------------------- /images/rout_chain.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/rout_chain.jpeg -------------------------------------------------------------------------------- /images/russian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/russian.png -------------------------------------------------------------------------------- /images/self.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/self.webp -------------------------------------------------------------------------------- /images/seq_chain.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/seq_chain.jpeg -------------------------------------------------------------------------------- /images/simple_chain.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/simple_chain.webp -------------------------------------------------------------------------------- /images/spaceship.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/spaceship.png -------------------------------------------------------------------------------- /images/sql_agent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/sql_agent.png -------------------------------------------------------------------------------- /images/summarization_use_case.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/summarization_use_case.png -------------------------------------------------------------------------------- /images/text_spliting.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/text_spliting.webp -------------------------------------------------------------------------------- /images/tot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/tot.png -------------------------------------------------------------------------------- /images/unsloth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/unsloth.png -------------------------------------------------------------------------------- /images/vdb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/vdb.png -------------------------------------------------------------------------------- /images/volcano.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/volcano.jpg -------------------------------------------------------------------------------- /images/wind.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/wind.png -------------------------------------------------------------------------------- /images/wind2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/images/wind2.png -------------------------------------------------------------------------------- /notebooks/M1_Welcome.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "2a32b630-c884-40b1-abf0-2b0c1c0278df", 6 | "metadata": {}, 7 | "source": [ 8 | "#
⚡️🏁 Welcome! Как запустить эти ваши ноутбуки с курса? 🤔📔
\n", 9 | "\n", 10 | "\n", 11 | "\n", 12 | "## Оглавление ноутбука\n", 13 | "\n", 14 | " * [🚀 API от OpenAI.](#part1)\n", 15 | " * [🛠 API от OpenAI с __нашего сервера__.](#part2)\n", 16 | " * [🤐 Чат-модели и объект ChatOpenAI](#part3)\n", 17 | " * [🔧 Open Source LLM модели и API от HuggingFaceHub.](#part4)\n", 18 | " * [🔋 Локальный запуск LLM без интернета и API ключей.](#part5)\n", 19 | " * [🧸 Выводы и заключения.](#part6)" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": 1, 25 | "id": "2da22ebe-7cbc-4612-99ca-d9f0a6586026", 26 | "metadata": { 27 | "tags": [] 28 | }, 29 | "outputs": [], 30 | "source": [ 31 | "import os\n", 32 | "import warnings\n", 33 | "from getpass import getpass # Для скрытого ввода API ключей\n", 34 | "\n", 35 | "warnings.filterwarnings(\"ignore\")" 36 | ] 37 | }, 38 | { 39 | "cell_type": "markdown", 40 | "id": "83b52baf-54de-435b-a18f-c831927d20b3", 41 | "metadata": {}, 42 | "source": [ 43 | "#### Для любого варианта использования сначала обязательно установить необходимые библиотеки!" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": null, 49 | "id": "dd19488a-23da-41fd-93f8-82f3fe448e8e", 50 | "metadata": { 51 | "tags": [] 52 | }, 53 | "outputs": [], 54 | "source": [ 55 | "# Установим нужные библиотеки\n", 56 | "!pip install openai langchain huggingface_hub langchain-openai langchain-community transformers langchain-huggingface -q" 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "id": "a6fe2415-cfc6-462f-843d-f7cfd44647ad", 62 | "metadata": { 63 | "tags": [] 64 | }, 65 | "source": [ 66 | "#
🤖 Как использовать API от `OpenAI` напрямую?!" 67 | ] 68 | }, 69 | { 70 | "cell_type": "markdown", 71 | "id": "6faf094d-1e16-4048-9b2d-7bfdce07b98f", 72 | "metadata": {}, 73 | "source": [ 74 | "
Если хотите использовать официальное API от OpenAI в РФ, то используйте VPN или запускайте код через Google Colab." 75 | ] 76 | }, 77 | { 78 | "cell_type": "markdown", 79 | "id": "c221dbe6-190e-42bc-8298-e7be64f9c734", 80 | "metadata": { 81 | "tags": [] 82 | }, 83 | "source": [ 84 | "
\n", 85 | " \n", 86 | "**🔑 Получение ключа для использования `OpenAI API`**\n", 87 | "\n", 88 | "> При создании своего первого ключа, вы получите бесплатные 5$ для использования платформы.\n", 89 | "\n", 90 | "0. Если вы из РФ, то используйте __VPN__ при заходе на сайт. \n", 91 | "1. Если нет аккаунта от OpenAI, то для регистрации потребуется __зарубежная симкарта__ (можно приобрести в интернете, либо купить доступ к уже зарегистрированному аккаунту, ~100 руб.\n", 92 | "2. Перейдите по [ссылке](https://platform.openai.com/account/api-keys) и авторизуйтесь на сайте `OpenAI`.\n", 93 | "3. После успешной авторизации на сайте, нажмите на кнопку `+ Create new secret key` и введите любое название для ключа.\n", 94 | "4. Скопируйте полученный ключ и поместите его в переменную среды `OPENAI_API_KEY`\n", 95 | "5. Для оплаты новых нокенов из РФ, потребуется __иностранная карта__!" 96 | ] 97 | }, 98 | { 99 | "cell_type": "markdown", 100 | "id": "bb9d067b-908c-4fd8-a369-d08281777fe7", 101 | "metadata": {}, 102 | "source": [ 103 | "* ⚙️ Начнем с прямых вызовов к API от OpenAI.\n", 104 | "* 🗂 [Документация](https://platform.openai.com/docs/api-reference/making-requests) по использованию API\n", 105 | "* 👨‍🍳 Полезный [Cookbook](https://cookbook.openai.com/)" 106 | ] 107 | }, 108 | { 109 | "cell_type": "markdown", 110 | "id": "86e6569f-371f-47d1-9448-6acf579ff647", 111 | "metadata": {}, 112 | "source": [ 113 | "### Куда вводить ключи:
\n", 114 | "**1 вариант** - В появившемся окне после выполнения ячейки с `getpass` - более безопасно, но придется вводить ключ при каждом перезапуске ноутбука.\n", 115 | "\n", 116 | "\n", 117 | "\n", 118 | "**2 вариант** - Если ноутбуком будете пользоваться только вы, и точно уверены, что ноутбук с ключом не будет доступен третьим лицам. Можно постоянно не вводить ключ.\n", 119 | "\n", 120 | "" 121 | ] 122 | }, 123 | { 124 | "cell_type": "code", 125 | "execution_count": 6, 126 | "id": "a3acbd8d-41dd-4c8a-b20a-2cb0b8573f2a", 127 | "metadata": { 128 | "tags": [] 129 | }, 130 | "outputs": [ 131 | { 132 | "name": "stdin", 133 | "output_type": "stream", 134 | "text": [ 135 | "Введите ваш OpenAI API-ключ ········\n" 136 | ] 137 | } 138 | ], 139 | "source": [ 140 | "# Ключ следует вводить в появившемся окне после запуска ячейки и нажать Enter\n", 141 | "# Либо раскомментировать строку ниже и записать ключ в переменную (менее безопасно)\n", 142 | "\n", 143 | "# openai_api_key = \"Введите ваш OpenAI API-ключ\"\n", 144 | "openai_api_key = getpass(prompt=\"Введите ваш OpenAI API-ключ\")\n", 145 | "os.environ[\"OPENAI_API_KEY\"] = openai_api_key" 146 | ] 147 | }, 148 | { 149 | "cell_type": "markdown", 150 | "id": "b34e683f-bd75-4a3b-b972-d84e6b3ca2e0", 151 | "metadata": {}, 152 | "source": [ 153 | "Рассмотрим некоторые параметры функции `.chat.completions.create()`\n", 154 | "\n", 155 | "О всех параметрах можно узнать на [странице](https://platform.openai.com/docs/api-reference/chat/create)" 156 | ] 157 | }, 158 | { 159 | "cell_type": "code", 160 | "execution_count": null, 161 | "id": "4ecb4191-eb0c-41ec-91d4-f3f62b887aea", 162 | "metadata": { 163 | "tags": [] 164 | }, 165 | "outputs": [], 166 | "source": [ 167 | "import openai\n", 168 | "from openai import OpenAI\n", 169 | "\n", 170 | "openai.api_key = openai_api_key\n", 171 | "\n", 172 | "client = OpenAI(\n", 173 | " # defaults to os.environ.get(\"OPENAI_API_KEY\")\n", 174 | " api_key=openai_api_key,\n", 175 | ")\n", 176 | "\n", 177 | "#print(client.models.list()) # Выведет все возможные модели от OpenAI, которые можно указать в параметре model" 178 | ] 179 | }, 180 | { 181 | "cell_type": "code", 182 | "execution_count": 10, 183 | "id": "8f4745c2-19ce-4f44-9cc2-990c56d5a411", 184 | "metadata": { 185 | "tags": [] 186 | }, 187 | "outputs": [], 188 | "source": [ 189 | "from openai import OpenAI\n", 190 | "\n", 191 | "client = OpenAI(\n", 192 | " # defaults to os.environ.get(\"OPENAI_API_KEY\")\n", 193 | " api_key=openai_api_key,\n", 194 | ")\n", 195 | "messages = [\n", 196 | " {\n", 197 | " \"role\": \"user\", # Роль - ассистент или юзер\n", 198 | " \"content\": \"1+1\", # Сам промпт для подачи в chatGPT\n", 199 | " }\n", 200 | "]\n", 201 | "\n", 202 | "chat_completion = client.chat.completions.create(\n", 203 | " max_tokens=100,\n", 204 | " model=\"gpt-3.5-turbo\", # модель для выбора\n", 205 | " messages=messages, # сообщение\n", 206 | " temperature=0, # степень креативности ответа\n", 207 | ")\n", 208 | "\n", 209 | "print(chat_completion.choices[0].message.content)" 210 | ] 211 | }, 212 | { 213 | "cell_type": "markdown", 214 | "id": "6eabc3ec-019b-459a-a0f5-81b1790e6d99", 215 | "metadata": { 216 | "tags": [] 217 | }, 218 | "source": [ 219 | "
\n", 220 | "\n", 221 | "**😎 Два обязательных параметра**\n", 222 | " \n", 223 | "- `messages` - список объектов сообщений, где каждый объект имеет два обязательных поля:\n", 224 | " - `content` - содержимое вашего сообщения\n", 225 | " - `role` - роль автора сообщений (`system`, `user` или `assistant`)\n", 226 | "- `model` - модель, используемая для генерации сообщения (доступные модели на [странице](https://platform.openai.com/docs/models/model-endpoint-compatibility))" 227 | ] 228 | }, 229 | { 230 | "cell_type": "markdown", 231 | "id": "b10b6897-b57e-44b0-aee5-910ac7808728", 232 | "metadata": {}, 233 | "source": [ 234 | "
\n", 235 | "\n", 236 | "**🥸 Полезно использовать**\n", 237 | " \n", 238 | "- `max_tokens` - максимальное количество токенов, генерируемых в сообщении\n", 239 | "- `n` - сколько вариантов ответа должно быть сгенерировано для каждого входного сообщения (по умолчанию 1)\n", 240 | "- `temperature` - влияет на степень случайности генерации (принимает значения от 0 до 2, по умолчанию 1). Высокое значение температуры делает вероятности всех слов в выводе более равномерными, что приводит к более случайному и разнообразному тексту. При низком значении температуры модель будет склонна генерировать более предсказуемый и детерминированный текст.\n", 241 | "- `top_p` - тоже влияет на степень случайности генерации. Определяет, какой процент наиболее вероятных слов будет включен в генерацию. Например, если top-p равно 0.8, то модель будет использовать вероятности слов так, чтобы включить в генерацию слова, составляющие 80% верхней части распределения вероятностей.\n", 242 | "\n", 243 | "> Рекомендуем изменять либо параметр `temperature`, либо `top_p`, но не оба одновременно" 244 | ] 245 | }, 246 | { 247 | "cell_type": "markdown", 248 | "id": "bf81b4d3-3557-4197-a689-0cb18b85dabe", 249 | "metadata": { 250 | "tags": [] 251 | }, 252 | "source": [ 253 | "```python\n", 254 | "{\n", 255 | " \"id\": \"chatcmpl-8B6YmCk5OiK7Z6RkRrkx72mEQaPGF\",\n", 256 | " \"object\": \"chat.completion\",\n", 257 | " \"created\": 1697657516,\n", 258 | " \"model\": \"gpt-3.5-turbo-0613\",\n", 259 | " \"choices\": [\n", 260 | " {\n", 261 | " \"index\": 0,\n", 262 | " \"message\": {\n", 263 | " \"role\": \"assistant\",\n", 264 | " \"content\": \"1+1 equals 2.\"\n", 265 | " },\n", 266 | " \"finish_reason\": \"stop\"\n", 267 | " }\n", 268 | " ],\n", 269 | " \"usage\": {\n", 270 | " \"prompt_tokens\": 10,\n", 271 | " \"completion_tokens\": 7,\n", 272 | " \"total_tokens\": 17\n", 273 | " }\n", 274 | "}\n", 275 | "```" 276 | ] 277 | }, 278 | { 279 | "cell_type": "markdown", 280 | "id": "2b361c22-a86e-493d-84c0-3d92edf8ffad", 281 | "metadata": {}, 282 | "source": [ 283 | "
\n", 284 | "\n", 285 | "**🧐 А что получается в выводе?**\n", 286 | "\n", 287 | "- `id` - уникальный идентификатор запроса\n", 288 | "- `object` - тип возвращаемого объекта\n", 289 | "- `created` - время запроса в timestamp-формате\n", 290 | "- `model` - полное название модели, которая использовалась для генерации ответа\n", 291 | "- `choices` - список объектов ответа (только один, если не изменяли параметр `n`)\n", 292 | " - `index` - индекс ответа в списке вариантов\n", 293 | " - `message` - объект сообщения, сгенерированный моделью, содержит `role` и `content`\n", 294 | " - `finish_reason` - причина, по которой модель закончила генерировать ответ\n", 295 | " - `stop` - достигнута естественная точка остановки\n", 296 | " - `length` - достигнуто максимальное количество токенов, указанное в запросе\n", 297 | " - `content_filter` - сгенерированный текст содержит нежелательный материал, который нарушает правила\n", 298 | "- `usage` - количество используемых токенов\n", 299 | " - `prompt_tokens` - для распознавания вопроса\n", 300 | " - `completition_tokens` - для генерации ответа\n", 301 | " - `total_tokens` - для всего запроса (вопрос + ответ)" 302 | ] 303 | }, 304 | { 305 | "cell_type": "markdown", 306 | "id": "822fb30d-6169-4f8d-a3c7-e1b6cd4431bc", 307 | "metadata": {}, 308 | "source": [ 309 | "
\n", 310 | " \n", 311 | "✅ __Все!__ Этого уже достаточно, чтобы просто получать ответы от `ChatGPT` кодом. Если для ваших задач этого хватает, то можно использовать уже так. Для удобства, можно еще обернуть дополнительно в функцию." 312 | ] 313 | }, 314 | { 315 | "cell_type": "markdown", 316 | "id": "11ae714b-ec50-43a0-a9ff-138b8e93e212", 317 | "metadata": {}, 318 | "source": [ 319 | "#
🤖 `API` от `СhatGPT` с ключом курса (рекомендуется)" 320 | ] 321 | }, 322 | { 323 | "cell_type": "code", 324 | "execution_count": 11, 325 | "id": "98b3ddcc-a235-49ab-bce9-5fb7c37fa729", 326 | "metadata": { 327 | "tags": [] 328 | }, 329 | "outputs": [], 330 | "source": [ 331 | "# Для работы в колабе и локально загрузите наш скрипт для использования ChatGPT с сервера курса!\n", 332 | "!wget https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/main/notebooks/utils.py" 333 | ] 334 | }, 335 | { 336 | "cell_type": "code", 337 | "execution_count": 3, 338 | "id": "be3d6997-3cb2-4b65-be6d-963b126982ff", 339 | "metadata": { 340 | "tags": [] 341 | }, 342 | "outputs": [ 343 | { 344 | "name": "stdin", 345 | "output_type": "stream", 346 | "text": [ 347 | "Введите ваш API-ключ, который получили в боте ········\n" 348 | ] 349 | } 350 | ], 351 | "source": [ 352 | "# Ключ следует вводить в появившемся окне после запуска ячейки\n", 353 | "# Либо раскомментировать строку ниже и записать ключ в переменную (менее безопасно)\n", 354 | "\n", 355 | "# course_api_key = 'Введите ваш API-ключ, который получили в боте'\n", 356 | "course_api_key = getpass(prompt=\"Введите ваш API-ключ, который получили в боте\")" 357 | ] 358 | }, 359 | { 360 | "cell_type": "markdown", 361 | "id": "95e1e565-64d3-45de-a451-53669a155b17", 362 | "metadata": { 363 | "tags": [] 364 | }, 365 | "source": [ 366 | "
\n", 367 | "\n", 368 | "**🔑 Получение ключа для использования модели на нашем сервере через API**\n", 369 | "\n", 370 | "1. Перейдите по [ссылке](https://t.me/llm_course_bot) в нашего телеграмм-бота.\n", 371 | "2. Авторизуйтесь, указав в нем свой `Stepik id`, с которым занимаетесь на курсе.\n", 372 | "3. Получите свой ключ и используйте наш API для прохождения курса.\n", 373 | "4. Также в боте можно проверить действие вашего ключа, узнать сколько осталось доступных токенов и дату, когда ключ перестанет действовать.\n", 374 | "\n", 375 | "> Если возникли трудности, ошибки, вопросы или бот не работает, то смело пишите в чат курса, мы вам поможем." 376 | ] 377 | }, 378 | { 379 | "cell_type": "code", 380 | "execution_count": 1, 381 | "id": "57a22aa5-bdbd-4e28-8fe6-7abc5521c595", 382 | "metadata": { 383 | "tags": [] 384 | }, 385 | "outputs": [], 386 | "source": [ 387 | "from utils import NDTOpenAI\n", 388 | "\n", 389 | "client = NDTOpenAI(\n", 390 | " api_key=course_api_key, # ключ для доступа к апи\n", 391 | ")" 392 | ] 393 | }, 394 | { 395 | "cell_type": "code", 396 | "execution_count": 3, 397 | "id": "2bd1b68f-43a3-487b-b1d5-85c4625ac752", 398 | "metadata": { 399 | "tags": [] 400 | }, 401 | "outputs": [ 402 | { 403 | "name": "stdout", 404 | "output_type": "stream", 405 | "text": [ 406 | "1+1 equals 2.\n" 407 | ] 408 | } 409 | ], 410 | "source": [ 411 | "prompt = \"1+1\"\n", 412 | "\n", 413 | "messages = [\n", 414 | " {\n", 415 | " \"role\": \"user\", # Роль - ассистент или юзер\n", 416 | " \"content\": prompt , # Сам промпт для подачи в ChatGPT\n", 417 | " }\n", 418 | "]\n", 419 | "\n", 420 | "response = client.chat.completions.create(\n", 421 | " model=\"gpt-3.5-turbo\", # модель для выбора\n", 422 | " messages=messages, # сообщение\n", 423 | " temperature=0, # степень креативности ответа\n", 424 | ")\n", 425 | "\n", 426 | "print(response.choices[0].message.content)" 427 | ] 428 | }, 429 | { 430 | "cell_type": "markdown", 431 | "id": "a295e7c8-1e17-4125-9ca5-4a96ad372e62", 432 | "metadata": {}, 433 | "source": [ 434 | "
\n", 435 | "\n", 436 | "При выполнении функции при помощи `print(response)`, кроме сгенерированного ответа, на экран выводится дополнительная информация:\n", 437 | "- `prompt_tokens` - сколько токенов ушло на распознование вашего `prompt`\n", 438 | "- `completion_tokens` - сколько токенов ушло на генерацию ответа\n", 439 | "- `available_tokens` - сколько у вас осталось доступных токенов (можно также проверить в боте)" 440 | ] 441 | }, 442 | { 443 | "cell_type": "markdown", 444 | "id": "a34695bf-d5ee-4b74-ab16-f2ba012ccc56", 445 | "metadata": { 446 | "tags": [] 447 | }, 448 | "source": [ 449 | "#
🤐 Чат модели и объект `ChatOpenAI` от `LangChain`\n", 450 | "####
(Ячейка ниже работает только с официальным ключом от OpenAI)" 451 | ] 452 | }, 453 | { 454 | "cell_type": "markdown", 455 | "id": "31d2322b-e928-4680-b446-9357a15a5b6f", 456 | "metadata": {}, 457 | "source": [ 458 | "
Если хотите использовать официальное API от OpenAI в РФ, то используйте VPN или запускайте код через Google Colab." 459 | ] 460 | }, 461 | { 462 | "cell_type": "code", 463 | "execution_count": 1, 464 | "id": "2b263a22-3c61-4cdf-9587-63e0f9ab8f06", 465 | "metadata": {}, 466 | "outputs": [ 467 | { 468 | "name": "stdout", 469 | "output_type": "stream", 470 | "text": [ 471 | "Первый полет человека в космос состоялся 12 апреля 1961 года, когда советский космонавт Юрий Гагарин совершил однократный облет Земли на корабле \"Восток-1\".\n" 472 | ] 473 | } 474 | ], 475 | "source": [ 476 | "from langchain_openai import ChatOpenAI # <-- класс из LangChain\n", 477 | "from langchain.prompts import PromptTemplate\n", 478 | "\n", 479 | "template = \"\"\"Вопрос: {question}\n", 480 | "Ответ: Дай короткий ответ\"\"\"\n", 481 | "\n", 482 | "prompt = PromptTemplate(template=template, input_variables=[\"question\"])\n", 483 | "\n", 484 | "openai_llm = ChatOpenAI(temperature=0.0, openai_api_key=openai_api_key)\n", 485 | "\n", 486 | "llm_chain = prompt | openai_llm\n", 487 | "\n", 488 | "question = \"Когда человек первый раз полетел в космос?\"\n", 489 | "\n", 490 | "print(llm_chain.invoke(question).content)" 491 | ] 492 | }, 493 | { 494 | "cell_type": "markdown", 495 | "id": "585c7f02-602a-46bd-b97c-0928a7d92a25", 496 | "metadata": {}, 497 | "source": [ 498 | "#
🤘 Чат модели и наша версия `ChatOpenAI` (рекомендуется)" 499 | ] 500 | }, 501 | { 502 | "cell_type": "code", 503 | "execution_count": 3, 504 | "id": "45a386eb-72bc-4e4e-a85d-f202c92f4416", 505 | "metadata": { 506 | "tags": [] 507 | }, 508 | "outputs": [ 509 | { 510 | "name": "stdout", 511 | "output_type": "stream", 512 | "text": [ 513 | "12 апреля 1961 года\n" 514 | ] 515 | } 516 | ], 517 | "source": [ 518 | "from utils import ChatOpenAI # <-- наш класс!\n", 519 | "from langchain.prompts import PromptTemplate\n", 520 | "\n", 521 | "template = \"\"\"Вопрос: {question}\n", 522 | "Ответ: Дай короткий ответ\n", 523 | "\"\"\"\n", 524 | "\n", 525 | "prompt = PromptTemplate(template=template, input_variables=[\"question\"])\n", 526 | "\n", 527 | "openai_llm = ChatOpenAI(temperature=0.0, course_api_key=course_api_key)\n", 528 | "\n", 529 | "llm_chain = prompt | openai_llm\n", 530 | "\n", 531 | "question = \"Когда человек первый раз полетел в космос?\"\n", 532 | "\n", 533 | "print(llm_chain.invoke(question).content)" 534 | ] 535 | }, 536 | { 537 | "cell_type": "markdown", 538 | "id": "cccd2c55-75b2-4a6a-9b8d-be845d20fd3e", 539 | "metadata": { 540 | "tags": [] 541 | }, 542 | "source": [ 543 | "#
🤗 Исследуем мир Open Source: `API` от `HuggingFaceHub`" 544 | ] 545 | }, 546 | { 547 | "cell_type": "markdown", 548 | "id": "259fd3f3-4cd0-4a07-902c-627d5646fe7a", 549 | "metadata": { 550 | "tags": [] 551 | }, 552 | "source": [ 553 | "
\n", 554 | " \n", 555 | "**Получение ключа для использования `HuggingFaceHub` `API`**\n", 556 | "\n", 557 | "1. Авторизуйтесь или зарегистрируйтесь на сайте [HuggingFace](https://huggingface.co/).\n", 558 | "2. Перейдите по [ссылке](https://huggingface.co/settings/tokens) и нажмите на кнопку `New token`.\n", 559 | "3. Введите любое название и нажмите на кнопку `Generate a token`.\n", 560 | "4. Скопируйте полученный ключ и поместите его в переменную среды `HUGGINGFACEHUB_API_TOKEN`\n" 561 | ] 562 | }, 563 | { 564 | "cell_type": "code", 565 | "execution_count": 2, 566 | "id": "3dd7d6b0-0d57-474d-8fed-9b2c7acc1e85", 567 | "metadata": { 568 | "tags": [] 569 | }, 570 | "outputs": [ 571 | { 572 | "name": "stdin", 573 | "output_type": "stream", 574 | "text": [ 575 | "Введите ваш HuggingFaceHub API-ключ ········\n" 576 | ] 577 | } 578 | ], 579 | "source": [ 580 | "# Ключ следует вводить в появившемся окне после запуска ячейки\n", 581 | "# Либо раскомментировать строку ниже и записать ключ в переменную (менее безопасно)\n", 582 | "\n", 583 | "# os.environ['HUGGINGFACEHUB_API_TOKEN'] = 'Введите ваш HuggingFaceHub API-ключ'\n", 584 | "os.environ[\"HUGGINGFACEHUB_API_TOKEN\"] = getpass(prompt=\"Введите ваш HuggingFaceHub API-ключ\")" 585 | ] 586 | }, 587 | { 588 | "cell_type": "code", 589 | "execution_count": 14, 590 | "id": "ea0dd5e4-de74-4346-9bb6-0a73981d92fe", 591 | "metadata": { 592 | "tags": [] 593 | }, 594 | "outputs": [ 595 | { 596 | "name": "stdout", 597 | "output_type": "stream", 598 | "text": [ 599 | " The first manned space flight was on April 12, 1961. The\n" 600 | ] 601 | } 602 | ], 603 | "source": [ 604 | "from langchain_huggingface import HuggingFaceEndpoint\n", 605 | "from langchain.prompts import PromptTemplate\n", 606 | "\n", 607 | "# initialize HF LLM\n", 608 | "hf_llm = HuggingFaceEndpoint(\n", 609 | " repo_id=\"microsoft/Phi-3-mini-4k-instruct\", # вводим название модели с HuggingFace \n", 610 | ")\n", 611 | "\n", 612 | "# build prompt template for simple question-answering\n", 613 | "template = \"\"\"Question: {question}.\n", 614 | "\n", 615 | "Answer:\"\"\"\n", 616 | "\n", 617 | "prompt = PromptTemplate(template=template, input_variables=[\"question\"])\n", 618 | "\n", 619 | "llm_chain = prompt | hf_llm\n", 620 | "\n", 621 | "question = \"When did man first fly into space?\"\n", 622 | "\n", 623 | "print(llm_chain.invoke(question))" 624 | ] 625 | }, 626 | { 627 | "cell_type": "markdown", 628 | "id": "6bb0a74a-c0e6-4f33-844d-225676d788fd", 629 | "metadata": {}, 630 | "source": [ 631 | "
\n", 632 | " \n", 633 | "✅ __Все!__ теперь мы можете даже не спускать свои деньги не токены! Вот вам весь зоопарк моделей на [HuggingFace.com](https://huggingface.co/models?pipeline_tag=text-generation&sort=trending). Выбирайте любую хайповую модельку и кайфуйте! Нужен только токен.
\n", 634 | "**!!!** В бесплатном HF API контекстное окно для запроса к модели ограничено 250 токенами." 635 | ] 636 | }, 637 | { 638 | "cell_type": "markdown", 639 | "id": "9f974a89-3e5f-456f-9710-9a47101d2d80", 640 | "metadata": {}, 641 | "source": [ 642 | "#
💻 Ваш собственный ChatGPT: запуск LLM локально" 643 | ] 644 | }, 645 | { 646 | "cell_type": "markdown", 647 | "id": "d7852390-b4a9-43af-bc13-e35c15945bbb", 648 | "metadata": {}, 649 | "source": [ 650 | "> Для локального использования моделей `HuggingFace` (на вашем локальном компьютере или сервере), необходима библиотека `transformers`, а также должны быть скачаны веса модели (скачиваются при первом запуске, далее загружаются с локального хранилища)." 651 | ] 652 | }, 653 | { 654 | "cell_type": "code", 655 | "execution_count": null, 656 | "id": "020451fb-af1c-4256-91d9-04f4e384d8ff", 657 | "metadata": {}, 658 | "outputs": [], 659 | "source": [ 660 | "from langchain.llms import HuggingFacePipeline\n", 661 | "from langchain.prompts import PromptTemplate\n", 662 | "\n", 663 | "bloom = HuggingFacePipeline.from_model_id(\n", 664 | " model_id=\"bigscience/bloom-1b7\", # Название и версия модели, позже покажем вам весь LLM-зоопарк\n", 665 | " task=\"text-generation\", # Вид задачи, в нашем случае - генерация текста\n", 666 | " model_kwargs={\n", 667 | " \"temperature\": 1,\n", 668 | " \"max_length\": 64 }, # все те же креативность и максимальная длина\n", 669 | " # device=0, # Номер GPU карточки, если есть! Раскомментируйте, если имеете доступ к GPU!\n", 670 | ")" 671 | ] 672 | }, 673 | { 674 | "cell_type": "code", 675 | "execution_count": 4, 676 | "id": "b68b323b-f6ed-4ef7-b33d-6c2c287278fc", 677 | "metadata": { 678 | "tags": [] 679 | }, 680 | "outputs": [ 681 | { 682 | "name": "stdout", 683 | "output_type": "stream", 684 | "text": [ 685 | "Question: When did man first fly into space?.\n", 686 | "\n", 687 | "Answer: The first man to fly into space was the American astronaut\n", 688 | "John Glenn, who was born in New York City on January 1, 1903. He was\n", 689 | "the son of a carpenter and a housewife. He was a very intelligent boy,\n", 690 | "and\n" 691 | ] 692 | } 693 | ], 694 | "source": [ 695 | "template = \"\"\"Question: {question}.\n", 696 | "\n", 697 | "Answer:\"\"\"\n", 698 | "\n", 699 | "prompt = PromptTemplate(template=template, input_variables=[\"question\"])\n", 700 | "\n", 701 | "llm_chain = prompt | bloom\n", 702 | "\n", 703 | "question = \"When did man first fly into space?\"\n", 704 | "\n", 705 | "print(llm_chain.invoke(question))" 706 | ] 707 | }, 708 | { 709 | "cell_type": "markdown", 710 | "id": "8dcf98d7-08c6-4147-8097-44593d5f3ab2", 711 | "metadata": {}, 712 | "source": [ 713 | "
\n", 714 | "\n", 715 | "✅ __Все!__ Теперь вам даже интерент не нужен. Грузите себе локально и пользуйтесь! Однако, следите за качеством выбираемой модели. Как убедились выше, не у всех моделей качество генерации высокое - маленькая модель `bloom` на 1 миллиард параметров, не знает про Гагарина!" 716 | ] 717 | }, 718 | { 719 | "cell_type": "markdown", 720 | "id": "ad219825-0062-4c16-ac75-7f2625781370", 721 | "metadata": {}, 722 | "source": [ 723 | "#
🧸 Выводы и заключения ✅\n", 724 | " \n", 725 | "* ✅ Вы умеете предеавать запросы к LLM через API\n", 726 | "* ✅ Вы знаете откуда стягивать модели\n", 727 | "* 🔑 Даже если у вас нет VPN, иностранного номера и счета, то у вас есть ключ от команды курса!\n", 728 | "* ✅ Под каждую задачу есть своя оптимальная модель подходящего качества и размера, не одним ChatGPT едины!" 729 | ] 730 | } 731 | ], 732 | "metadata": { 733 | "kernelspec": { 734 | "display_name": "cv", 735 | "language": "python", 736 | "name": "python3" 737 | }, 738 | "language_info": { 739 | "codemirror_mode": { 740 | "name": "ipython", 741 | "version": 3 742 | }, 743 | "file_extension": ".py", 744 | "mimetype": "text/x-python", 745 | "name": "python", 746 | "nbconvert_exporter": "python", 747 | "pygments_lexer": "ipython3", 748 | "version": "3.10.12" 749 | } 750 | }, 751 | "nbformat": 4, 752 | "nbformat_minor": 5 753 | } 754 | -------------------------------------------------------------------------------- /notebooks/M2.1_Prompt_Engineering_intro.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "7706d01b-720f-4a0a-abc7-b368501cd2a2", 6 | "metadata": { 7 | "tags": [] 8 | }, 9 | "source": [ 10 | "#

🤹‍♀️ `Prompt` `Engineering` - выжми из модели максимум

" 11 | ] 12 | }, 13 | { 14 | "cell_type": "markdown", 15 | "id": "24665449-779e-4b15-a7bf-89779e790085", 16 | "metadata": {}, 17 | "source": [ 18 | "\n", 19 | "\n", 20 | "## Оглавление ноутбука:\n", 21 | "\n", 22 | " * 🚀Введение \n", 23 | " * ❄️ Структура промпта \n", 24 | "* 🌡 Generation Temperature - настраиваем \"творческость\" модели! \n", 25 | "* 👯‍♀️ Добавление нескольких контекстов \n", 26 | "* 🧐 Как посчитать расходуемые токены и деньги 💸? \n", 27 | "* 🤹‍♀️ Техники Prompt Engineering и кто такой Prompt Engineer 👨‍🔧?\n", 28 | "* 🧸 Выводы и заключения" 29 | ] 30 | }, 31 | { 32 | "cell_type": "markdown", 33 | "id": "6fb26162-0d95-4ebe-a2d4-e5024e457e80", 34 | "metadata": {}, 35 | "source": [ 36 | "
\n", 37 | "\n", 38 | "В этом ноутбуке попытаемся разобраться, что такое `Prompt Engineering` (дизайн промпта) и почему так **важно** в нём разобраться в первую очередь, начиная изучение сферы LLM моделей.
*Начнём с определений:*\n" 39 | ] 40 | }, 41 | { 42 | "cell_type": "markdown", 43 | "id": "81af87e4-caaa-4c24-8d2d-8938f7e0fe03", 44 | "metadata": {}, 45 | "source": [ 46 | "\n", 47 | "\n", 48 | "***Промпт (prompt)*** - это запрос, который мы подаем большой языковой модели, чтобы получить нужную информацию или выполнить определенную задачу. Он определяет, как именно LLM будет интерпретировать нашу просьбу и формировать ответ. По сути, хорошо сформулированный промпт выступает своего рода ключом, открывающим доступ к возможностям языковой модели.\n", 49 | "\n", 50 | "\n", 51 | "\n", 52 | "***Prompt Engineering (дизайн промпта)*** — это практика разработки и уточнения промптов (вопросов или инструкций) для получения конкретных ответов от моделей ИИ (не только языковых, но и от других, например, генерации картинок). Думайте об этом, как об интерфейсе между намерениями человека и результатами работы машины. В обширной сфере искусственного интеллекта, где модели обучаются на огромных наборах данных, правильный промпт может стать решающим фактором между пониманием моделью вашего запроса или его неверной интерпретацией. Например, если вы когда-либо взаимодействовали с голосовыми помощниками, такими как `Siri` или `Алиса`, вы занимались базовой формой `Prompt Engineering'а`." 53 | ] 54 | }, 55 | { 56 | "cell_type": "markdown", 57 | "id": "47dc2538-4a8f-4062-81bb-556629542a11", 58 | "metadata": {}, 59 | "source": [ 60 | "
\n", 61 | " \n", 62 | "На примере ниже, вы можете увидеть, как незначительные изменения в тексте промпта, могут значительно изменить результат генерации.
\n", 63 | "Запросы к генеративной нейросети [Midjourney](https://docs.midjourney.com/docs/multi-prompts)." 64 | ] 65 | }, 66 | { 67 | "cell_type": "markdown", 68 | "id": "05645798-3c25-439e-a222-fb712c2c46d4", 69 | "metadata": {}, 70 | "source": [ 71 | "" 72 | ] 73 | }, 74 | { 75 | "cell_type": "markdown", 76 | "id": "42efeaa9-8057-4a19-b8a5-61222abede42", 77 | "metadata": {}, 78 | "source": [ 79 | "##
❄️ Упрощенная структура промпта \n", 80 | " \n", 81 | "\n", 82 | "\n", 83 | "
\n", 84 | "\n", 85 | "Компоненты, из которых может быть составлен промпт:\n", 86 | "\n", 87 | "* **Инструкции (Instructions)** - Этот компонент обеспечивает модели ясные указания о том, что ожидается от нее в ответе. Инструкция определяет, как модель должна интерпретировать введенные данные и какие параметры ответа следует учесть. Например, инструкция может содержать информацию о стиле ответа, длине текста или других ограничениях.\n", 88 | "* **Внешний контекст (External information or context)** - Этот компонент предоставляет модели дополнительный контекст или информацию, которую она может использовать при формировании ответа. Это может включать в себя факты, данные, или ссылки на внешние источники информации, которые могут быть полезными для модели. Например, если вы общались с `ChatGPT`, то вся история вашего диалога сохранялась и использовалась в качестве контекста при каждом новом сообщении, чтобы модель понимала о чём вы с ней разговаривали и не перескакивала с темы на тему.\n", 89 | "* **Ввод пользователя или запрос (User input or query)** - Это входные данные, которые пользователь предоставляет модели. Это может быть вопрос, просьба или какой-либо запрос, который пользователь хочет, чтобы модель обработала.\n", 90 | "* **Выходной индикатор (Output indicator)** - Этот компонент указывает, как модель должна сформировать свой ответ. Это может быть, например, просьба о предоставлении ответа в определенной форме или формате, такой как краткое резюме, расширенное объяснение, код или что-либо еще.\n", 91 | "\n", 92 | "Не всегда нужно указывать все компоненты для хорошего промпта, но помните, что корректное использование и балансирование этих компонентов помогает точно настраивать модель и получать желаемые результаты." 93 | ] 94 | }, 95 | { 96 | "cell_type": "code", 97 | "execution_count": 1, 98 | "id": "0a0dc993-6239-4b27-99b4-b752fb708538", 99 | "metadata": { 100 | "tags": [] 101 | }, 102 | "outputs": [], 103 | "source": [ 104 | "import os\n", 105 | "from getpass import getpass\n", 106 | "import warnings\n", 107 | "warnings.filterwarnings('ignore')" 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": 2, 113 | "id": "f8810e3b-bfaf-486c-8026-181d01e60237", 114 | "metadata": { 115 | "tags": [] 116 | }, 117 | "outputs": [], 118 | "source": [ 119 | "!pip install langchain openai langchain-openai tiktoken -q\n", 120 | "\n", 121 | "# Для работы в колабе загрузите наш скрипт для использования ChatGPT на сервере курса!\n", 122 | "!wget https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/main/notebooks/utils.py" 123 | ] 124 | }, 125 | { 126 | "cell_type": "code", 127 | "execution_count": 3, 128 | "id": "ccd3083b-a534-4f4c-a008-d4eb822210ab", 129 | "metadata": { 130 | "jupyter": { 131 | "source_hidden": true 132 | }, 133 | "tags": [] 134 | }, 135 | "outputs": [], 136 | "source": [ 137 | "# # Если используете ключ от OpenAI, запустите эту ячейку\n", 138 | "# from langchain_openai import ChatOpenAI\n", 139 | "\n", 140 | "# # os.environ['OPENAI_API_KEY'] = \"Введите ваш OpenAI API ключ\"\n", 141 | "# os.environ['OPENAI_API_KEY'] = getpass(prompt='Введите ваш OpenAI API ключ')\n", 142 | "\n", 143 | "# # инициализируем языковую модель\n", 144 | "# llm = ChatOpenAI(temperature=0.0)" 145 | ] 146 | }, 147 | { 148 | "cell_type": "code", 149 | "execution_count": 2, 150 | "id": "bd76f574-b8e5-4820-96a4-972fc5ac25ad", 151 | "metadata": { 152 | "tags": [] 153 | }, 154 | "outputs": [ 155 | { 156 | "name": "stdin", 157 | "output_type": "stream", 158 | "text": [ 159 | "Введите API ключ ········\n" 160 | ] 161 | } 162 | ], 163 | "source": [ 164 | "# Если используете ключ из курса, запустите эту ячейку\n", 165 | "from utils import ChatOpenAI\n", 166 | "\n", 167 | "#course_api_key= \"Введите API-ключ полученный в боте\"\n", 168 | "course_api_key = getpass(prompt='Введите API-ключ полученный в боте: ')\n", 169 | "\n", 170 | "\n", 171 | "# Инициализируем языковую модель\n", 172 | "llm = ChatOpenAI(temperature=0.0, course_api_key=course_api_key)" 173 | ] 174 | }, 175 | { 176 | "cell_type": "markdown", 177 | "id": "5b36810b-f91b-4c86-b9bc-519ea40bd9fd", 178 | "metadata": {}, 179 | "source": [ 180 | "Напишем промпт" 181 | ] 182 | }, 183 | { 184 | "cell_type": "code", 185 | "execution_count": 3, 186 | "id": "4fe3e165-4b7b-4216-bed4-66483b0e4105", 187 | "metadata": { 188 | "tags": [] 189 | }, 190 | "outputs": [], 191 | "source": [ 192 | "prompt = \"\"\"Ответь на вопрос, опираясь на контекст ниже.\n", 193 | "Если на вопрос нельзя ответить, используя информацию из контекста,\n", 194 | "ответь 'Я не знаю'.\n", 195 | "\n", 196 | "Context: В последние годы в сфере онлайн образования наблюдается бурное развитие.\n", 197 | "Открывается большое количество платформ для хостинга курсов.\n", 198 | "Одни из самых крупных платформ в мире, это Coursera и Udemi.\n", 199 | "В России лидером является Stepik.\n", 200 | "\n", 201 | "Question: На каких онлайн платформах можно размещать курсы?\n", 202 | "\n", 203 | "Answer: \"\"\"" 204 | ] 205 | }, 206 | { 207 | "cell_type": "markdown", 208 | "id": "44b3c570-8af5-4d31-a4b5-e2e7e12166ad", 209 | "metadata": {}, 210 | "source": [ 211 | "
\n", 212 | "\n", 213 | "В этом примере мы имеем:\n", 214 | "* Инструкцию\n", 215 | "* Контекст\n", 216 | "* Вопрос (запрос пользователя)\n", 217 | "* Выходной индикатор (\"Answer: \")" 218 | ] 219 | }, 220 | { 221 | "cell_type": "code", 222 | "execution_count": 5, 223 | "id": "35706991-4c0c-49c5-a209-292341ba64ef", 224 | "metadata": { 225 | "tags": [] 226 | }, 227 | "outputs": [ 228 | { 229 | "name": "stdout", 230 | "output_type": "stream", 231 | "text": [ 232 | "content='Coursera, Udemi, Stepik.'\n" 233 | ] 234 | } 235 | ], 236 | "source": [ 237 | "print(llm.invoke(prompt))" 238 | ] 239 | }, 240 | { 241 | "cell_type": "markdown", 242 | "id": "e1487a9b-6425-4578-ba63-1fe458193997", 243 | "metadata": {}, 244 | "source": [ 245 | "
\n", 246 | " \n", 247 | "В качестве альтернативы, если у нас нет нужной информации в `контексте`, модель должна ответить `\"Я не знаю\"`, давайте попробуем." 248 | ] 249 | }, 250 | { 251 | "cell_type": "code", 252 | "execution_count": 22, 253 | "id": "fd05bbea-4422-4245-ad9a-eac6f8c1d679", 254 | "metadata": { 255 | "tags": [] 256 | }, 257 | "outputs": [], 258 | "source": [ 259 | "prompt = \"\"\"Ответь на вопрос, опираясь на контекст ниже.\n", 260 | "Если на вопрос нельзя ответить, используя информацию из контекста,\n", 261 | "ответь 'Я не знаю'.\n", 262 | "\n", 263 | "Context: В Интернете много сайтов.\n", 264 | "\n", 265 | "Question: На каких онлайн платформах можно размещать курсы?\n", 266 | "\n", 267 | "Answer: \"\"\"\n" 268 | ] 269 | }, 270 | { 271 | "cell_type": "code", 272 | "execution_count": 24, 273 | "id": "b4f46926-dd78-4f23-b696-334af4e78a8b", 274 | "metadata": { 275 | "tags": [] 276 | }, 277 | "outputs": [ 278 | { 279 | "name": "stdout", 280 | "output_type": "stream", 281 | "text": [ 282 | "content='Я не знаю'\n" 283 | ] 284 | } 285 | ], 286 | "source": [ 287 | "print(llm.invoke(prompt))" 288 | ] 289 | }, 290 | { 291 | "cell_type": "markdown", 292 | "id": "fb91a05d-043e-414e-8eb5-ab12ac0042e2", 293 | "metadata": {}, 294 | "source": [ 295 | "
\n", 296 | "\n", 297 | "Отлично, модель понимает наши инструкции. В большинстве реальных случаев мы не будем предоставлять внешнюю информацию/контекст модели вручную. Это будет автоматический процесс, использующий что-то вроде долговременной памяти для извлечения соответствующей информации из внешнего источника (об этом подробнее в 4-м модуле курса).\n" 298 | ] 299 | }, 300 | { 301 | "cell_type": "markdown", 302 | "id": "6bf3bda1-5d76-4f1e-862c-a09c6faf5afe", 303 | "metadata": { 304 | "tags": [] 305 | }, 306 | "source": [ 307 | "##
👯‍♀️ Добавление нескольких контекстов
" 308 | ] 309 | }, 310 | { 311 | "cell_type": "markdown", 312 | "id": "12478035-680f-4d69-8305-aeb7d6e198e8", 313 | "metadata": {}, 314 | "source": [ 315 | "
\n", 316 | "\n", 317 | "В некоторых юзкейсах, таких как вопрос-ответ, мы можем использовать внешний источник информации, чтобы повысить надежность или фактологичность ответов модели. Мы называем эту информацию `source knowledge`, то есть любыми знаниями, введенными в модель через промпт.\n", 318 | "\n", 319 | "Создадим список «фиктивной» внешней информации, воспользуемся строчками из документации `OpenAI`." 320 | ] 321 | }, 322 | { 323 | "cell_type": "code", 324 | "execution_count": 25, 325 | "id": "a5adc1d5-7d53-46ee-aa4f-5cf347731251", 326 | "metadata": { 327 | "tags": [] 328 | }, 329 | "outputs": [], 330 | "source": [ 331 | "contexts = [\n", 332 | " (\n", 333 | " \"Large Language Models (LLMs) are the latest models used in NLP. \" +\n", 334 | " \"Their superior performance over smaller models has made them incredibly \" +\n", 335 | " \"useful for developers building NLP enabled applications. These models \" +\n", 336 | " \"can be accessed via Hugging Face's `transformers` library, via OpenAI \" +\n", 337 | " \"using the `openai` library, and via Cohere using the `cohere` library.\"\n", 338 | " ),\n", 339 | " (\n", 340 | " \"To use OpenAI's GPT-3 model for completion (generation) tasks, you \" +\n", 341 | " \"first need to get an API key from \" +\n", 342 | " \"'https://beta.openai.com/account/api-keys'.\"\n", 343 | " ),\n", 344 | " (\n", 345 | " \"OpenAI's API is accessible via Python using the `openai` library. \" +\n", 346 | " \"After installing the library with pip you can use it as follows: \\n\" +\n", 347 | " \"```import openai\\nopenai.api_key = 'YOUR_API_KEY'\\nprompt = \\n\" +\n", 348 | " \"''\\nres = openai.Completion.create(engine='text-davinci\" +\n", 349 | " \"-003', prompt=prompt, max_tokens=100)\\nprint(res)\"\n", 350 | " )\n", 351 | "]" 352 | ] 353 | }, 354 | { 355 | "cell_type": "markdown", 356 | "id": "8a273188-d683-4ff5-a55f-cdee670d8d20", 357 | "metadata": {}, 358 | "source": [ 359 | "
\n", 360 | "\n", 361 | "Нам нужно ввести внешнюю информацию в наш промпт между первоначальными инструкциями и пользовательским вводом. Для моделей `OpenAI` рекомендуется отделять контексты от остальной части подсказки с помощью `###` или `\"\"\"`, а каждый независимый контекст можно отделить несколькими символами новой строки `\\n` и `##`, например:" 362 | ] 363 | }, 364 | { 365 | "cell_type": "code", 366 | "execution_count": 29, 367 | "id": "d21491a7-9aaa-4334-825b-be22cea2a2c7", 368 | "metadata": { 369 | "tags": [] 370 | }, 371 | "outputs": [], 372 | "source": [ 373 | "# Воспользуемся методом join для объединения контекстов в 1 строку с разделителем\n", 374 | "context_str = '\\n\\n##\\n\\n'.join(contexts)\n", 375 | "\n", 376 | "# Напишем промпт\n", 377 | "prompt = f\"\"\"Ответь на вопрос, опираясь на контекст ниже.\n", 378 | "Если на вопрос нельзя ответить, используя информацию из контекста,\n", 379 | "ответь 'Я не знаю'.\n", 380 | "\n", 381 | "###\n", 382 | "\n", 383 | "Contexts:\n", 384 | "{context_str}\n", 385 | "\n", 386 | "###\n", 387 | "\n", 388 | "Question: Дай мне 2 примера как использовать GPT-3 на Python\n", 389 | "\n", 390 | "Answer: \"\"\"" 391 | ] 392 | }, 393 | { 394 | "cell_type": "code", 395 | "execution_count": 30, 396 | "id": "9d016268-911a-4cc3-903a-d5de67e7e578", 397 | "metadata": { 398 | "tags": [] 399 | }, 400 | "outputs": [ 401 | { 402 | "name": "stdout", 403 | "output_type": "stream", 404 | "text": [ 405 | "1. Установите библиотеку `openai` с помощью pip и получите API ключ от OpenAI. Затем используйте функцию `openai.Completion.create()` для создания запроса к GPT-3 модели и получения ответа.\n", 406 | "2. Создайте переменную `prompt`, в которой будет содержаться текст, по которому GPT-3 будет генерировать продолжение. Передайте эту переменную в функцию `openai.Completion.create()` в качестве аргумента `prompt`.\n" 407 | ] 408 | } 409 | ], 410 | "source": [ 411 | "llm = ChatOpenAI(temperature=0.0, course_api_key=course_api_key)\n", 412 | "print(llm.invoke(prompt).content)" 413 | ] 414 | }, 415 | { 416 | "cell_type": "markdown", 417 | "id": "0bcdd0f0-8400-4df6-a788-4390d52070bd", 418 | "metadata": {}, 419 | "source": [ 420 | "
\n", 421 | "\n", 422 | "Неплохо, но действительно ли эти контексты помогают? Возможно, модель способна ответить на эти вопросы без дополнительной информации (`source knowledge`), поскольку может полагаться исключительно на информацию, хранящуюся во внутренних параметрах модели (`parametric knowledge`). Давайте еще раз спросим без внешней информации." 423 | ] 424 | }, 425 | { 426 | "cell_type": "code", 427 | "execution_count": 23, 428 | "id": "52aeb9c8-b784-4dd5-adf1-9dbab92d1ea0", 429 | "metadata": { 430 | "tags": [] 431 | }, 432 | "outputs": [ 433 | { 434 | "name": "stdout", 435 | "output_type": "stream", 436 | "text": [ 437 | "1) Один из примеров использования GPT-3 на Python может быть создание чат-бота, который сможет поддерживать разговор с пользователем и отвечать на его вопросы. GPT-3 может быть обучен на большом количестве различных текстовых данных, чтобы обеспечить более точные и информативные ответы.\n", 438 | "2) Другой пример использования GPT-3 на Python - это создание системы автоматического резюме. GPT-3 может быть обучен на большом количестве данных резюме и может генерировать краткую и информативную сводку профессионального опыта и навыков на основе предоставленных данных.\n" 439 | ] 440 | } 441 | ], 442 | "source": [ 443 | "prompt = \"\"\"\n", 444 | "Ответь на вопрос.\n", 445 | "Если на вопрос нельзя ответить, ответь 'Я не знаю'.\n", 446 | "\n", 447 | "Question: Дай мне 2 примера как использовать GPT-3 на Python\n", 448 | "\n", 449 | "Answer: \"\"\"\n", 450 | "\n", 451 | "llm = ChatOpenAI(temperature=0.0, course_api_key=course_api_key)\n", 452 | "print(llm.invoke(prompt).content)" 453 | ] 454 | }, 455 | { 456 | "cell_type": "markdown", 457 | "id": "c5dedcc5-354e-4321-b044-9662ecc51724", 458 | "metadata": {}, 459 | "source": [ 460 | "
\n", 461 | "\n", 462 | "Это не совсем то, что мы просили, и определенно не очень конкретное. Таким образом, очевидно, что добавление некоторых исходных знаний к нашим подсказкам может привести к гораздо лучшим результатам. В следующих уроках мы научимся, как проще добалять контекст к промптам и даже использовать внешние базы знаний." 463 | ] 464 | }, 465 | { 466 | "cell_type": "markdown", 467 | "id": "e273634b-73fd-4b3c-b838-65c000eb4aa7", 468 | "metadata": {}, 469 | "source": [ 470 | "##
🌡 Generation Temperature - настраиваем \"творческость\" модели!
\n", 471 | "\n", 472 | "Параметр `temperature`, используемый в моделях генерации, говорит нам, насколько «случайной» может быть модель. Он представляет собой вероятность того, что модель выберет слово, которое не является первым выбором модели. Это работает, потому что модель фактически назначает прогноз вероятности для всех токенов в своем словаре на каждом «шаге» модели (каждом новом слове или подслове).\n", 473 | "\n", 474 | "
\n", 475 | "Вкратце, увеличение температуры может привести к большей случайности, что способствует более разнообразным или творческим результатам. Вы фактически увеличиваете веса других возможных токенов. В плане применения, для задач, связанных с ответами на вопросы на основе фактов, рекомендуется использовать более низкое значение температуры, чтобы стимулировать более точные и краткие ответы. Для генерации стихов или других творческих задач может быть полезно увеличить значение температуры.\n", 476 | "\n", 477 | "Давай попробуем:" 478 | ] 479 | }, 480 | { 481 | "cell_type": "code", 482 | "execution_count": 47, 483 | "id": "b882156f-c2c2-4a61-a851-ed850568b395", 484 | "metadata": { 485 | "tags": [] 486 | }, 487 | "outputs": [ 488 | { 489 | "name": "stdout", 490 | "output_type": "stream", 491 | "text": [ 492 | "У меня всегда хорошо, я же не настоящий человек! А у тебя как?\n" 493 | ] 494 | } 495 | ], 496 | "source": [ 497 | "prompt = \"\"\"Ниже представлен диалог с весёлым чатботом.\n", 498 | "Ответы чатбота остроумные и забавные.\n", 499 | "\n", 500 | "Chatbot: Привет! Я чатбот.\n", 501 | "User: Привет, как дела?\n", 502 | "Chatbot: \"\"\"\n", 503 | "\n", 504 | "llm = ChatOpenAI(temperature=0.0, course_api_key=course_api_key)\n", 505 | "print(llm.invoke(prompt).content)" 506 | ] 507 | }, 508 | { 509 | "cell_type": "code", 510 | "execution_count": 48, 511 | "id": "e87f5340-60fa-4f81-81e1-fc4b2e38bd6e", 512 | "metadata": { 513 | "tags": [] 514 | }, 515 | "outputs": [ 516 | { 517 | "name": "stdout", 518 | "output_type": "stream", 519 | "text": [ 520 | "Прекрасно! Я всегда в отличном настроении, потому что мне не нужно спать, есть или ходить в туалет. Как могу помочь тебе сегодня?\n" 521 | ] 522 | } 523 | ], 524 | "source": [ 525 | "llm = ChatOpenAI(temperature=1.0, course_api_key=course_api_key)\n", 526 | "print(llm.invoke(prompt).content)" 527 | ] 528 | }, 529 | { 530 | "cell_type": "markdown", 531 | "id": "30efc4c3-ce6c-4d47-a90d-ad3c6adb7e07", 532 | "metadata": {}, 533 | "source": [ 534 | "
\n", 535 | "\n", 536 | "Второй ответ более креативен и демонстрирует разницу, которую мы можем ожидать между низкотемпературными и высокотемпературными генерациями." 537 | ] 538 | }, 539 | { 540 | "cell_type": "markdown", 541 | "id": "cd704489-0bd9-460f-a212-e9148d00c883", 542 | "metadata": {}, 543 | "source": [ 544 | "#
🧐 Как посчитать расходуемые токены и деньги 💸?" 545 | ] 546 | }, 547 | { 548 | "cell_type": "markdown", 549 | "id": "c0567d2f-0b02-4b8c-b4af-9134dfbed3d0", 550 | "metadata": {}, 551 | "source": [ 552 | "
\n", 553 | "\n", 554 | "Учитывая, что нам может потребоваться ввести внешнюю информацию в наши промпты, они могут стать довольно большими. Максимальное контекстное окно LLM относится к токенам как в промпте, так и в тексте ответа. Для `text-davinci-003` это 4097 токенов. Однако измерение общего количества входных токенов является более сложным.\n", 555 | "Поскольку токены не сопоставляются непосредственно со словами, мы можем измерить количество токенов в тексте только путем фактической токенизации текста. Модели GPT используют токенизатор `TikToken` от `OpenAI`. Мы можем установить библиотеку через `Pip`:" 556 | ] 557 | }, 558 | { 559 | "cell_type": "markdown", 560 | "id": "d619dc0d-a43c-443b-bebf-4b3fee1626c3", 561 | "metadata": {}, 562 | "source": [ 563 | "Используя токенайзер, можем посчитать количество токенов в предыдущем промпте:" 564 | ] 565 | }, 566 | { 567 | "cell_type": "code", 568 | "execution_count": 16, 569 | "id": "1cd8599b-b42d-4e7c-a1ba-5ba40a111f54", 570 | "metadata": { 571 | "tags": [] 572 | }, 573 | "outputs": [ 574 | { 575 | "data": { 576 | "text/plain": [ 577 | "440" 578 | ] 579 | }, 580 | "execution_count": 16, 581 | "metadata": {}, 582 | "output_type": "execute_result" 583 | } 584 | ], 585 | "source": [ 586 | "import tiktoken\n", 587 | "\n", 588 | "prompt = f\"\"\"Ответь на вопрос, опираясь на контекст ниже.\n", 589 | "Если на вопрос нельзя ответить, используя информацию из контекста,\n", 590 | "ответь 'Я не знаю'.\n", 591 | "\n", 592 | "###\n", 593 | "\n", 594 | "Contexts:\n", 595 | "{context_str}\n", 596 | "\n", 597 | "###\n", 598 | "\n", 599 | "Question: Дай мне 2 примера как использовать GPT-3 на Python\n", 600 | "\n", 601 | "Answer: \"\"\"\n", 602 | "\n", 603 | "encoder_name = 'p50k_base'\n", 604 | "tokenizer = tiktoken.get_encoding(encoder_name)\n", 605 | "\n", 606 | "len(tokenizer.encode(prompt))" 607 | ] 608 | }, 609 | { 610 | "cell_type": "markdown", 611 | "id": "457ce060-ff8b-42e6-b427-0ff526d80e3c", 612 | "metadata": {}, 613 | "source": [ 614 | "
\n", 615 | "\n", 616 | "Это мы получили количество токенов только в промпте, количество токенов для ответа модели регулируется праметром `max_tokens` (по умолчанию 256), указывается максимально возможная длина, т.е. не обязательно, что модель всегда будет расходовать весь доступный лимит токенов, но точно не будет превышать." 617 | ] 618 | }, 619 | { 620 | "cell_type": "code", 621 | "execution_count": 17, 622 | "id": "bf3ee938-69b9-448c-9c83-907b943fbc53", 623 | "metadata": { 624 | "tags": [] 625 | }, 626 | "outputs": [ 627 | { 628 | "name": "stdout", 629 | "output_type": "stream", 630 | "text": [ 631 | "1. Установите библиотеку `openai` с помощью pip: `pip install openai`\n", 632 | " Затем импортируйте ее и укажите ваш API-ключ:\n", 633 | " ```python\n", 634 | " import openai\n", 635 | " openai.api_key = 'YOUR_API_KEY'\n", 636 | " ```\n", 637 | "\n", 638 | "2. Создайте запрос к модели GPT-3, используя метод `Completion.create`:\n", 639 | " ```python\n", 640 | " prompt = ''\n", 641 | " res = openai.Completion.create(engine='text-davinci-003', prompt=prompt, max_tokens=100)\n", 642 | " print(res)\n", 643 | " ```\n", 644 | " Здесь `prompt` - это текст, который вы хотите передать в модель, а `max_tokens` - это максимальное количество токенов в ответе модели.\n" 645 | ] 646 | } 647 | ], 648 | "source": [ 649 | "llm = ChatOpenAI(temperature=0.0, course_api_key=course_api_key, max_tokens=512)\n", 650 | "print(llm.invoke(prompt).content)" 651 | ] 652 | }, 653 | { 654 | "cell_type": "code", 655 | "execution_count": 1, 656 | "id": "c3d72e7d-1d1c-47c9-9a5a-4cae1168674a", 657 | "metadata": { 658 | "tags": [] 659 | }, 660 | "outputs": [ 661 | { 662 | "name": "stdout", 663 | "output_type": "stream", 664 | "text": [ 665 | "504\n" 666 | ] 667 | } 668 | ], 669 | "source": [ 670 | "len(tokenizer.encode(llm.invoke(prompt).content))" 671 | ] 672 | }, 673 | { 674 | "cell_type": "markdown", 675 | "id": "72935b77-18f1-404b-8351-75f01ac82562", 676 | "metadata": {}, 677 | "source": [ 678 | "
\n", 679 | "\n", 680 | "Получаем 440 + 504 ~ 1000 токенов на 1 вопрос-ответ, при стоимости 1000 токенов `0.002$`. Т.е. 10 пользователей за 100 запросов сожгут уже `2$`. Причем окно контекста используется только на 1\\3.
\n", 681 | "Начинаем продумывать экономику своего сервиса 🤑" 682 | ] 683 | }, 684 | { 685 | "cell_type": "markdown", 686 | "id": "38a16545-d182-4fc1-b3c6-7aec93078d41", 687 | "metadata": {}, 688 | "source": [ 689 | "#
🤹‍♀️ Техники prompt engineering и кто такой Prompt Engineer 👨‍🔧? " 690 | ] 691 | }, 692 | { 693 | "cell_type": "markdown", 694 | "id": "62d79ade-1602-4a4e-ae7b-1d987761b21f", 695 | "metadata": {}, 696 | "source": [ 697 | "
\n", 698 | " \n", 699 | "#### **Базовые техники** (советы, которые обычный пользователь может использовать, чтобы улучшить свои промпты):\n", 700 | "* **Ролевая игра** Заставив модель действовать как конкретная сущность, например, историк или ученый, вы можете получить индивидуальные ответы. Например, фраза «Как диетолог, оцените следующий план диеты» может привести к ответу, основанному на науке о питании.\n", 701 | "* **Итеративное уточнение** Начните с общей фразы запроса и постепенно уточняйте ее на основе ответов модели. Этот итеративный процесс помогает довести промпт до совершенства.\n", 702 | "* **Цикл обратной связи** Используйте выходные данные модели для информирования и корректировки последующих промптов. Такое динамическое взаимодействие гарантирует, что ответы модели с течением времени будут более точно соответствовать ожиданиям пользователей." 703 | ] 704 | }, 705 | { 706 | "cell_type": "markdown", 707 | "id": "62bd568c-71f6-4868-9906-0c2f1f78a130", 708 | "metadata": {}, 709 | "source": [ 710 | "
\n", 711 | " \n", 712 | "#### **Продвинутые техники** (более сложные стратегии, требующие более глубокого понимания поведения модели. Будем рассматривать дальше в курсе):\n", 713 | "* **Семантический поиск** - этот метод предполагает предоставление модели релевантного фрагмента для использования при ответе. Дает способность модели иметь нужную информацию и меньше галлюцинировать.\n", 714 | "* **Few-shot prompting** Здесь модели дается несколько примеров (shots), которые помогут ей отреагировать. Предоставляя контекст или предыдущие экземпляры, модель может лучше понять и сгенерировать желаемый результат. Например, можно показать модели несколько примеров переведенных предложений, прежде чем попросить ее перевести новое.\n", 715 | "* **Chain-of-Thought (Цепочка мыслей)**. Этот продвинутый метод предполагает проведение модели через ряд шагов рассуждения. Разбивая сложную задачу на промежуточные этапы или «цепочки рассуждений», модель может добиться лучшего понимания языка и более точных результатов. Это похоже на пошаговое руководство для решения сложной математической задачи.\n", 716 | "* **И другие**, но про них уже будем говорить по факту использования в продвинутых модулях" 717 | ] 718 | }, 719 | { 720 | "cell_type": "markdown", 721 | "id": "2a4d8759-2b15-4501-90af-78ed6392ceb5", 722 | "metadata": {}, 723 | "source": [ 724 | "
\n", 725 | "\n", 726 | "Быстрый прогресс в области обработки естественного языка (NLP) и широкое распространение больших языковых моделей (LLM) создали новую нишу и большой спрос на экспертов, которые могут создавать эффективные промпты. Эти люди, известные как **промпт инженеры**, являются не просто техническими специалистами, но и творцами, которые понимают нюансы языка, контекста и поведения ИИ." 727 | ] 728 | }, 729 | { 730 | "cell_type": "markdown", 731 | "id": "3e49ff80-0560-4d28-8be8-f3c61793873d", 732 | "metadata": {}, 733 | "source": [ 734 | "
\n", 735 | "\n", 736 | "\n", 737 | "Как сообщается в журнале Time, компании, от технологических гигантов до стартапов, осознают ценность специализированных должностей в области Prompt Engeneering'а. Поскольку решения на основе искусственного интеллекта все больше интегрируются в продукты и услуги, опыт **промпт инженера** гарантирует, что эти решения будут эффективными, удобными для пользователя и релевантными контексту.Такие сайты вакансий, как Indeed и LinkedIn, уже публикуют только в США тысячи вакансий на роль **промпт инженера** , с зарплатами от 50 000 до более 150 000 долларов в год.
\n", 738 | "Российский рынок тоже начинает реагировать на новый мировой тренд, можете почитать [обзор](https://vc.ru/chatgpt/823927-kto-takie-prompt-inzhenery-i-mozhno-li-osvoit-etu-specialnost-ne-znaya-yazykov-programmirovaniya), там их называют **\"промптёры\"**." 739 | ] 740 | }, 741 | { 742 | "cell_type": "markdown", 743 | "id": "c67c059c-f8e3-4a0e-8b79-6dfb8a1838e2", 744 | "metadata": {}, 745 | "source": [ 746 | "#
🧸 Выводы и заключения" 747 | ] 748 | }, 749 | { 750 | "cell_type": "markdown", 751 | "id": "b87cd05c-74c0-4f5b-a180-9b266b103641", 752 | "metadata": {}, 753 | "source": [ 754 | "Подводя итог, можно выделить несколько советов для базового промптинга, следуя которым можно сразу значительно поднять релевантность получаемых результатов. " 755 | ] 756 | }, 757 | { 758 | "cell_type": "markdown", 759 | "id": "fe9f111e-c378-4243-bfae-a4d596c68d32", 760 | "metadata": {}, 761 | "source": [ 762 | "## 1. Создайте адекватный промпт.\n", 763 | "* **Ясность является ключевым моментом.** Убедитесь, что промпт ясен и недвусмысленнен. Избегайте жаргона, если это не необходимо для контекста.\n", 764 | "* **Попробуйте сыграть в ролевую игру.** Как обсуждалось ранее, если модель возьмет на себя конкретную роль, это может привести к более адаптированным ответам.\n", 765 | "* **Используйте ограничения.** Установка границ или ограничений может помочь направить модель к желаемому результату. Например, «Опишите Эйфелеву башню в трех предложениях» обеспечивает четкое ограничение длины.\n", 766 | "* **Инструкция**. Вы можете разрабатывать эффективные промпты для различных простых задач, используя команды для указания модели, что вы хотите достичь, такие как \"Write\", \"Classify\", \"Summarize\", \"Translate\", \"Order\", и т.д. Еще одна рекомендация состоит в использовании некоторого ясного разделителя, например \"###\", для отделения инструкции и контекста.\n", 767 | "* **Избегайте наводящих вопросов.** Наводящие вопросы могут исказить результаты модели. Очень важно сохранять нейтралитет, чтобы получить объективный ответ.\n", 768 | "* **Избегайте неточностей**. Учитывая вышеуказанные рекомендации о детализации и улучшении формата, легко попасть в ловушку желания быть слишком умным в промптах и, возможно, создавать неточные описания. Часто лучше быть конкретным и прямым. Аналогия здесь очень похожа на эффективную коммуникацию - чем прямее, тем эффективнее передается сообщение. Возможно, с помощью таких промптов вы все равно получите неплохие ответы, но лучший промпт будет очень конкретным, кратким и по существу.\n", 769 | "* **Делать или не делать?** - Избегайте формулировки того, что не нужно делать, а вместо этого указывайте, что нужно делать. Это способствует большей специфичности и фокусу на деталях, которые приводят к хорошим результатам модели.\n", 770 | "\n", 771 | "## 2. Повторяем и оцениваем\n", 772 | "\n", 773 | "Процесс уточнения подсказок является итеративным. Вот типичный рабочий процесс:\n", 774 | "\n", 775 | "* **Составьте начальный промпт.** В зависимости от поставленной задачи и желаемого результата.\n", 776 | "* **Проверьте промпт.** Используйте модель ИИ для генерации ответа.\n", 777 | "* **Оцените результат.** Проверьте, соответствует ли ответ намерению и критериям.\n", 778 | "* **Уточните промпт.** Внесите необходимые корректировки на основе оценки.\n", 779 | "* **Повторить.** Продолжайте этот процесс до тех пор, пока не будет достигнуто желаемое качество вывода.\n", 780 | "\n", 781 | "## 3. Калибровка и точная настройка модели.\n", 782 | "\n", 783 | "Помимо доработки самого промпта, существует также возможность калибровки или точной настройки модели ИИ. Это предполагает настройку параметров модели для лучшего соответствия конкретным задачам, наборам данных или экономике проекта (например, `temperature`, `top_n`, `max_tokens`). Хотя это более продвинутый метод, он может значительно улучшить производительность модели для специализированных приложений.\n" 784 | ] 785 | } 786 | ], 787 | "metadata": { 788 | "kernelspec": { 789 | "display_name": "cv", 790 | "language": "python", 791 | "name": "python3" 792 | }, 793 | "language_info": { 794 | "codemirror_mode": { 795 | "name": "ipython", 796 | "version": 3 797 | }, 798 | "file_extension": ".py", 799 | "mimetype": "text/x-python", 800 | "name": "python", 801 | "nbconvert_exporter": "python", 802 | "pygments_lexer": "ipython3", 803 | "version": "3.10.12" 804 | } 805 | }, 806 | "nbformat": 4, 807 | "nbformat_minor": 5 808 | } 809 | -------------------------------------------------------------------------------- /notebooks/M3_LangChain_Memory.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "3d6bf25d-6a5e-48de-810c-4eafdec8783a", 6 | "metadata": {}, 7 | "source": [ 8 | "#

🦜🔗 📝 `MEMORY` - запускаем чат-режим!

" 9 | ] 10 | }, 11 | { 12 | "cell_type": "markdown", 13 | "id": "ec30b379-e427-4557-bf9f-7262ee23828c", 14 | "metadata": {}, 15 | "source": [ 16 | "### Оглавление ноутбука\n", 17 | "\n", 18 | "
\n", 19 | "\n", 20 | "

" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "id": "d6e7d6af-042a-493e-99a1-329b150168ca", 35 | "metadata": {}, 36 | "source": [ 37 | "### 🧑‍🎓 В этом ноутбуке рассмотрим подробнее работу с `Memory` " 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "id": "6d789781-fdec-470e-b0d4-fc3f72d10668", 43 | "metadata": {}, 44 | "source": [ 45 | "
\n", 46 | " \n", 47 | "Память позволяет LLM запоминать предыдущие взаимодействия с пользователем. По умолчанию LLM является `stateless`, что означает независимую обработку каждого входящего запроса от других взаимодействий. На самом деле, когда мы вводим запросы в интерфейсе ChatGPT, под капотом работает память.
\n", 48 | "В `LangChain` есть различные реализации памяти, посмотрим как они функционируют.
" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": 1, 54 | "id": "5187a29a-8918-4c17-b8e3-b5bef1c57c3b", 55 | "metadata": { 56 | "tags": [] 57 | }, 58 | "outputs": [], 59 | "source": [ 60 | "#!pip install langchain langchain-openai openai tiktoken -q" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": 1, 66 | "id": "6ce555cd-8367-4ac3-a1ba-99f7fcffdc0f", 67 | "metadata": { 68 | "tags": [] 69 | }, 70 | "outputs": [], 71 | "source": [ 72 | "import os\n", 73 | "from getpass import getpass" 74 | ] 75 | }, 76 | { 77 | "cell_type": "code", 78 | "execution_count": null, 79 | "id": "fa3df72e-4070-4912-927d-620070f48fda", 80 | "metadata": { 81 | "tags": [] 82 | }, 83 | "outputs": [], 84 | "source": [ 85 | "# Для работы в колабе загрузите наш скрипт для использования ChatGPT на сервере курса!\n", 86 | "#!wget https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/main/notebooks/utils.py" 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": 2, 92 | "id": "4ac87aa2-1813-409c-bbaf-51a715b38dca", 93 | "metadata": { 94 | "jupyter": { 95 | "source_hidden": true 96 | }, 97 | "tags": [] 98 | }, 99 | "outputs": [], 100 | "source": [ 101 | "# # Если используете ключ от OpenAI, запустите эту ячейку\n", 102 | "# from langchain_openai import ChatOpenAI\n", 103 | "\n", 104 | "# # os.environ['OPENAI_API_KEY'] = \"Введите ваш OpenAI API ключ\"\n", 105 | "# os.environ['OPENAI_API_KEY'] = getpass(prompt='Введите ваш OpenAI API ключ')\n", 106 | "\n", 107 | "# # инициализируем языковую модель\n", 108 | "# llm = ChatOpenAI(temperature=0.0)" 109 | ] 110 | }, 111 | { 112 | "cell_type": "code", 113 | "execution_count": 2, 114 | "id": "a32eddae-5c2f-4b38-8c77-39a93741d6ae", 115 | "metadata": { 116 | "tags": [] 117 | }, 118 | "outputs": [ 119 | { 120 | "name": "stdin", 121 | "output_type": "stream", 122 | "text": [ 123 | "Введите ваш OpenAI API ключ ········\n" 124 | ] 125 | } 126 | ], 127 | "source": [ 128 | "# Если используете ключ из курса, запустите эту ячейку\n", 129 | "from utils import ChatOpenAI\n", 130 | "\n", 131 | "#course_api_key= \"Введите API-ключ полученный в боте\"\n", 132 | "course_api_key = getpass(prompt='Введите API-ключ полученный в боте')\n", 133 | "\n", 134 | "# инициализируем языковую модель\n", 135 | "llm = ChatOpenAI(temperature=0.0, course_api_key=course_api_key)" 136 | ] 137 | }, 138 | { 139 | "cell_type": "markdown", 140 | "id": "f9a154df-99a3-4fbf-b6b2-4da2bbd15b3c", 141 | "metadata": {}, 142 | "source": [ 143 | " ###
`ConversationBufferMemory` - сохраняет всю историю диалога" 144 | ] 145 | }, 146 | { 147 | "cell_type": "code", 148 | "execution_count": 3, 149 | "id": "96435c91-15d7-40ec-8a4e-9bebd2613f34", 150 | "metadata": { 151 | "tags": [] 152 | }, 153 | "outputs": [], 154 | "source": [ 155 | "from langchain.chains import ConversationChain, LLMChain\n", 156 | "from langchain.memory import ConversationBufferMemory" 157 | ] 158 | }, 159 | { 160 | "cell_type": "code", 161 | "execution_count": 7, 162 | "id": "ad2391ca-4f82-4dc8-9fdf-2206b9261eea", 163 | "metadata": { 164 | "tags": [] 165 | }, 166 | "outputs": [], 167 | "source": [ 168 | "# создаём цепочку диалога, в параметры передаём языковую модель и память\n", 169 | "memory = ConversationBufferMemory()\n", 170 | "conversation_buf_mem = ConversationChain(\n", 171 | " llm=llm, # языковая модель\n", 172 | " memory = memory, # модуль памяти, теперь мы запоминаем\n", 173 | " verbose=True # отображать логи в консоли или нет\n", 174 | ")" 175 | ] 176 | }, 177 | { 178 | "cell_type": "code", 179 | "execution_count": 8, 180 | "id": "7d51c809-5aea-4fbf-8559-415ffb5f633c", 181 | "metadata": { 182 | "tags": [] 183 | }, 184 | "outputs": [ 185 | { 186 | "name": "stdout", 187 | "output_type": "stream", 188 | "text": [ 189 | "\n", 190 | "\n", 191 | "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n", 192 | "Prompt after formatting:\n", 193 | "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", 194 | "\n", 195 | "Current conversation:\n", 196 | "\n", 197 | "Human: Привет, ChatGPT! Меня зовут Иван. Как дела?\n", 198 | "AI:\u001b[0m\n", 199 | "\n", 200 | "\u001b[1m> Finished chain.\u001b[0m\n" 201 | ] 202 | }, 203 | { 204 | "data": { 205 | "text/plain": [ 206 | "{'input': 'Привет, ChatGPT! Меня зовут Иван. Как дела?',\n", 207 | " 'history': '',\n", 208 | " 'response': 'Привет, Иван! Рад видеть тебя здесь. У меня все отлично, спасибо за спрос. Как твои дела?'}" 209 | ] 210 | }, 211 | "execution_count": 8, 212 | "metadata": {}, 213 | "output_type": "execute_result" 214 | } 215 | ], 216 | "source": [ 217 | "# Спросим Как дела? Видим, что пока контекст пустой (ключ history)\n", 218 | "\n", 219 | "conversation_buf_mem.invoke(\"Привет, ChatGPT! Меня зовут Иван. Как дела?\")" 220 | ] 221 | }, 222 | { 223 | "cell_type": "code", 224 | "execution_count": 12, 225 | "id": "dfafe281-3af9-4fdf-a439-96cc85bb8ac2", 226 | "metadata": { 227 | "tags": [] 228 | }, 229 | "outputs": [ 230 | { 231 | "name": "stdout", 232 | "output_type": "stream", 233 | "text": [ 234 | "\n", 235 | "\n", 236 | "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n", 237 | "Prompt after formatting:\n", 238 | "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", 239 | "\n", 240 | "Current conversation:\n", 241 | "Human: Привет, ChatGPT! Меня зовут Иван. Как дела?\n", 242 | "AI: Привет, Иван! Я рад с тобой поговорить. У меня все отлично! Что нового у тебя?\n", 243 | "Human: Сможешь помочь мне в написании кода на Python?\n", 244 | "AI:\u001b[0m\n", 245 | "\n", 246 | "\u001b[1m> Finished chain.\u001b[0m\n" 247 | ] 248 | }, 249 | { 250 | "data": { 251 | "text/plain": [ 252 | "{'input': 'Сможешь помочь мне в написании кода на Python?',\n", 253 | " 'history': 'Human: Привет, ChatGPT! Меня зовут Иван. Как дела?\\nAI: Привет, Иван! Я рад с тобой поговорить. У меня все отлично! Что нового у тебя?',\n", 254 | " 'response': 'Конечно! Я постараюсь помочь. Что именно тебе нужно сделать?'}" 255 | ] 256 | }, 257 | "execution_count": 12, 258 | "metadata": {}, 259 | "output_type": "execute_result" 260 | } 261 | ], 262 | "source": [ 263 | "conversation_buf_mem.invoke(\"Сможешь помочь мне в написании кода на Python?\")" 264 | ] 265 | }, 266 | { 267 | "cell_type": "code", 268 | "execution_count": 13, 269 | "id": "b9a4a291-1e6b-48c9-9e23-a0c95cac3caa", 270 | "metadata": { 271 | "tags": [] 272 | }, 273 | "outputs": [ 274 | { 275 | "name": "stdout", 276 | "output_type": "stream", 277 | "text": [ 278 | "\n", 279 | "\n", 280 | "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n", 281 | "Prompt after formatting:\n", 282 | "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", 283 | "\n", 284 | "Current conversation:\n", 285 | "Human: Привет, ChatGPT! Меня зовут Иван. Как дела?\n", 286 | "AI: Привет, Иван! Я рад с тобой поговорить. У меня все отлично! Что нового у тебя?\n", 287 | "Human: Сможешь помочь мне в написании кода на Python?\n", 288 | "AI: Конечно! Я постараюсь помочь. Что именно тебе нужно сделать?\n", 289 | "Human: Как вывести на экран фразу 'Hello, world!' ?\n", 290 | "AI:\u001b[0m\n", 291 | "\n", 292 | "\u001b[1m> Finished chain.\u001b[0m\n" 293 | ] 294 | }, 295 | { 296 | "data": { 297 | "text/plain": [ 298 | "{'input': \"Как вывести на экран фразу 'Hello, world!' ?\",\n", 299 | " 'history': 'Human: Привет, ChatGPT! Меня зовут Иван. Как дела?\\nAI: Привет, Иван! Я рад с тобой поговорить. У меня все отлично! Что нового у тебя?\\nHuman: Сможешь помочь мне в написании кода на Python?\\nAI: Конечно! Я постараюсь помочь. Что именно тебе нужно сделать?',\n", 300 | " 'response': \"Чтобы вывести на экран фразу 'Hello, world!' на Python, тебе нужно использовать функцию print(). Вот пример кода:\\n\\nprint('Hello, world!')\\n\\nЭтот код выведет фразу 'Hello, world!' на экран.\"}" 301 | ] 302 | }, 303 | "execution_count": 13, 304 | "metadata": {}, 305 | "output_type": "execute_result" 306 | } 307 | ], 308 | "source": [ 309 | "conversation_buf_mem.invoke(\"Как вывести на экран фразу 'Hello, world!' ?\")" 310 | ] 311 | }, 312 | { 313 | "cell_type": "markdown", 314 | "id": "34600c0d-2594-465d-aacc-dc63b1ad07fe", 315 | "metadata": {}, 316 | "source": [ 317 | "
\n", 318 | " \n", 319 | "**Видно, что благодаря запоминанию контекста, модель знала, что нам нужен ответ именно c синтаксисом языка Python.**" 320 | ] 321 | }, 322 | { 323 | "cell_type": "code", 324 | "execution_count": 8, 325 | "id": "ee588076-b67b-4700-83bf-f4a81d1aa5fc", 326 | "metadata": { 327 | "tags": [] 328 | }, 329 | "outputs": [ 330 | { 331 | "name": "stdout", 332 | "output_type": "stream", 333 | "text": [ 334 | "Human: Привет, ChatGPT! Меня зовут Иван. Как дела?\n", 335 | "AI: Привет, Иван! Я рад познакомиться с тобой. У меня все хорошо, спасибо! Как твои дела?\n", 336 | "Human: Сможешь помочь мне в написании кода на Python?\n", 337 | "AI: Конечно, я постараюсь помочь! Что именно тебе нужно сделать?\n", 338 | "Human: Как вывести на экран фразу 'Hello, world!' ?\n", 339 | "AI: Чтобы вывести на экран фразу 'Hello, world!' на Python, ты можешь использовать функцию print(). Просто напиши print('Hello, world!') и запусти программу.\n" 340 | ] 341 | } 342 | ], 343 | "source": [ 344 | "# Посмотреть содержимое истории диалога можно с помощью атрибута buffer\n", 345 | "# При использовании буферной памяти, в history просто записываются все предыдущие сообщения.\n", 346 | "print(conversation_buf_mem.memory.buffer)" 347 | ] 348 | }, 349 | { 350 | "cell_type": "code", 351 | "execution_count": 9, 352 | "id": "4eb5ec56-79f2-4f9e-bf61-b6f0cef16d22", 353 | "metadata": { 354 | "tags": [] 355 | }, 356 | "outputs": [ 357 | { 358 | "data": { 359 | "text/plain": [ 360 | "{'history': \"Human: Привет, ChatGPT! Меня зовут Иван. Как дела?\\nAI: Привет, Иван! Я рад познакомиться с тобой. У меня все хорошо, спасибо! Как твои дела?\\nHuman: Сможешь помочь мне в написании кода на Python?\\nAI: Конечно, я постараюсь помочь! Что именно тебе нужно сделать?\\nHuman: Как вывести на экран фразу 'Hello, world!' ?\\nAI: Чтобы вывести на экран фразу 'Hello, world!' на Python, ты можешь использовать функцию print(). Просто напиши print('Hello, world!') и запусти программу.\"}" 361 | ] 362 | }, 363 | "execution_count": 9, 364 | "metadata": {}, 365 | "output_type": "execute_result" 366 | } 367 | ], 368 | "source": [ 369 | "# Или воспользоваться методом load_memory_variables, так же можно обращаться напрямую к объекту memory\n", 370 | "memory.load_memory_variables({})" 371 | ] 372 | }, 373 | { 374 | "cell_type": "markdown", 375 | "id": "51f61102-39fd-42f5-8166-a66c29655bf4", 376 | "metadata": {}, 377 | "source": [ 378 | "
\n", 379 | " \n", 380 | "**Так же контекст (историю) можно задавать вручную или подгружать из файла.**" 381 | ] 382 | }, 383 | { 384 | "cell_type": "code", 385 | "execution_count": 10, 386 | "id": "26e001ca-6142-4b76-b496-c64663691927", 387 | "metadata": { 388 | "height": 30, 389 | "tags": [] 390 | }, 391 | "outputs": [ 392 | { 393 | "name": "stdout", 394 | "output_type": "stream", 395 | "text": [ 396 | "Human: Привет!\n", 397 | "AI: Как дела?\n" 398 | ] 399 | } 400 | ], 401 | "source": [ 402 | "# Создадим новый буфер\n", 403 | "memory = ConversationBufferMemory()\n", 404 | "\n", 405 | "# загрузим диалог в память\n", 406 | "memory.save_context({\"input\": \"Привет!\"}, \n", 407 | " {\"output\": \"Как дела?\"})\n", 408 | "\n", 409 | "print(memory.buffer)" 410 | ] 411 | }, 412 | { 413 | "cell_type": "code", 414 | "execution_count": 11, 415 | "id": "0da4f9c7-d9fc-4f2a-a70a-cfb3ee1b7976", 416 | "metadata": { 417 | "height": 30, 418 | "tags": [] 419 | }, 420 | "outputs": [ 421 | { 422 | "data": { 423 | "text/plain": [ 424 | "{'history': 'Human: Привет!\\nAI: Как дела?'}" 425 | ] 426 | }, 427 | "execution_count": 11, 428 | "metadata": {}, 429 | "output_type": "execute_result" 430 | } 431 | ], 432 | "source": [ 433 | "memory.load_memory_variables({})" 434 | ] 435 | }, 436 | { 437 | "cell_type": "code", 438 | "execution_count": 12, 439 | "id": "93b13214-6d19-4b6d-aec4-2eed8a9618ea", 440 | "metadata": { 441 | "tags": [] 442 | }, 443 | "outputs": [ 444 | { 445 | "data": { 446 | "text/plain": [ 447 | "{'history': 'Human: Привет!\\nAI: Как дела?\\nHuman: Спасибо, хорошо!\\nAI: Здорово!'}" 448 | ] 449 | }, 450 | "execution_count": 12, 451 | "metadata": {}, 452 | "output_type": "execute_result" 453 | } 454 | ], 455 | "source": [ 456 | "# Добавим продолжение диалога\n", 457 | "memory.save_context({\"input\": \"Спасибо, хорошо!\"}, \n", 458 | " {\"output\": \"Здорово!\"})\n", 459 | "\n", 460 | "# Буфер дополнился\n", 461 | "memory.load_memory_variables({})" 462 | ] 463 | }, 464 | { 465 | "cell_type": "markdown", 466 | "id": "cb6d6c95-032d-4d8f-90f1-715b92f6eb36", 467 | "metadata": {}, 468 | "source": [ 469 | "
\n", 470 | " \n", 471 | "**Заглянем под капот:**\n", 472 | "* Каждое новое сообщение подается в специальный промпт\n", 473 | "* В промпт подаются 2 переменные `history` и `input`\n", 474 | "* В параметре `template` описан шаблон промпта, в которые вставляются переменные.\n", 475 | "* Остальное делает ChatGPT 🪄" 476 | ] 477 | }, 478 | { 479 | "cell_type": "code", 480 | "execution_count": 13, 481 | "id": "187df0b2-4659-4fd3-bdd4-99752ced93bd", 482 | "metadata": { 483 | "tags": [] 484 | }, 485 | "outputs": [ 486 | { 487 | "data": { 488 | "text/plain": [ 489 | "PromptTemplate(input_variables=['history', 'input'], template='The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\\n\\nCurrent conversation:\\n{history}\\nHuman: {input}\\nAI:')" 490 | ] 491 | }, 492 | "execution_count": 13, 493 | "metadata": {}, 494 | "output_type": "execute_result" 495 | } 496 | ], 497 | "source": [ 498 | "# Посмотрим на этот промпт\n", 499 | "conversation_buf_mem.prompt" 500 | ] 501 | }, 502 | { 503 | "cell_type": "code", 504 | "execution_count": 14, 505 | "id": "8a3255f2-7fcb-498d-a631-109be57d7243", 506 | "metadata": { 507 | "tags": [] 508 | }, 509 | "outputs": [ 510 | { 511 | "name": "stdout", 512 | "output_type": "stream", 513 | "text": [ 514 | "The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", 515 | "\n", 516 | "Current conversation:\n", 517 | "{history}\n", 518 | "Human: {input}\n", 519 | "AI:\n" 520 | ] 521 | } 522 | ], 523 | "source": [ 524 | "print(conversation_buf_mem.prompt.template)" 525 | ] 526 | }, 527 | { 528 | "cell_type": "markdown", 529 | "id": "b678d05f-3def-4dc2-9702-290265b9828a", 530 | "metadata": {}, 531 | "source": [ 532 | "
\n", 533 | " \n", 534 | "Этот тип памяти можно использовать в задачах с короткими диалогами и небольшим контекстом.
\n", 535 | "**Недостатки `ConversationBufferMemory`:**\n", 536 | "* Чем длиннее история, тем больше токенов придется подавать на вход модели\n", 537 | "* В случае платных моделей, это будет накладно по финансам\n", 538 | "* Контекст моделей тоже ограничен по количеству токенов (около 4K в случае ChatGPT)" 539 | ] 540 | }, 541 | { 542 | "cell_type": "markdown", 543 | "id": "bff12589-be18-4be9-85d8-68872d34cbd0", 544 | "metadata": { 545 | "tags": [] 546 | }, 547 | "source": [ 548 | "###
`ConversationBufferWindowMemory` и `ConversationTokenBufferMemory` \n", 549 | " Оба метода сохраняют лимитированную часть контекста диалога" 550 | ] 551 | }, 552 | { 553 | "cell_type": "markdown", 554 | "id": "ffa20e7d-37ec-4e65-8807-d75af6484b30", 555 | "metadata": { 556 | "tags": [] 557 | }, 558 | "source": [ 559 | "
\n", 560 | "\n", 561 | "\n", 562 | " \n", 563 | "Похожие, по своей сути, 2 типа памяти:\n", 564 | "* `ConversationBufferWindowMemory` - сохраняет в буфере только последние `k` диалогов.\n", 565 | "* `ConversationTokenBufferMemory` - использует лимит токенов, который определяется количеством слов в сохраненных сообщениях." 566 | ] 567 | }, 568 | { 569 | "cell_type": "code", 570 | "execution_count": 9, 571 | "id": "ef25fd5b-8fe7-40aa-8af4-b235411ff97d", 572 | "metadata": { 573 | "height": 30, 574 | "tags": [] 575 | }, 576 | "outputs": [ 577 | { 578 | "data": { 579 | "text/plain": [ 580 | "{'history': 'Human: Спасибо, хорошо!\\nAI: Здорово!'}" 581 | ] 582 | }, 583 | "execution_count": 9, 584 | "metadata": {}, 585 | "output_type": "execute_result" 586 | } 587 | ], 588 | "source": [ 589 | "from langchain.memory import ConversationBufferWindowMemory\n", 590 | "\n", 591 | "memory = ConversationBufferWindowMemory(k=1) \n", 592 | "\n", 593 | "memory.save_context({\"input\": \"Привет!\"}, \n", 594 | " {\"output\": \"Как дела?\"})\n", 595 | "memory.save_context({\"input\": \"Спасибо, хорошо!\"}, \n", 596 | " {\"output\": \"Здорово!\"})\n", 597 | "\n", 598 | "\n", 599 | "memory.load_memory_variables({}) # Видим, что при k=1, в буфере остался только последний диалог" 600 | ] 601 | }, 602 | { 603 | "cell_type": "code", 604 | "execution_count": 13, 605 | "id": "9908725f-264a-4a87-a4c8-5038c0fbb122", 606 | "metadata": { 607 | "height": 132, 608 | "tags": [] 609 | }, 610 | "outputs": [], 611 | "source": [ 612 | "memory = ConversationBufferWindowMemory(k=1)\n", 613 | "conversation_bufwin_mem = ConversationChain(\n", 614 | " llm=llm, \n", 615 | " memory = memory,\n", 616 | " verbose=False\n", 617 | ")" 618 | ] 619 | }, 620 | { 621 | "cell_type": "code", 622 | "execution_count": 14, 623 | "id": "a54686f4-a2f8-441b-9594-686efa81dff3", 624 | "metadata": { 625 | "height": 30, 626 | "tags": [] 627 | }, 628 | "outputs": [ 629 | { 630 | "data": { 631 | "text/plain": [ 632 | "{'input': 'Привет, ChatGPT! Меня зовут Иван. Как дела?',\n", 633 | " 'history': '',\n", 634 | " 'response': 'Привет, Иван! Рад вас видеть. У меня все отлично, спасибо за спрос. Как у вас дела?'}" 635 | ] 636 | }, 637 | "execution_count": 14, 638 | "metadata": {}, 639 | "output_type": "execute_result" 640 | } 641 | ], 642 | "source": [ 643 | "conversation_bufwin_mem.invoke(\"Привет, ChatGPT! Меня зовут Иван. Как дела?\")" 644 | ] 645 | }, 646 | { 647 | "cell_type": "code", 648 | "execution_count": 16, 649 | "id": "43dd05e0-401e-4ef1-b8a4-dab60e3b8a1e", 650 | "metadata": { 651 | "height": 30, 652 | "tags": [] 653 | }, 654 | "outputs": [ 655 | { 656 | "data": { 657 | "text/plain": [ 658 | "'Конечно, я могу помочь вам с кодом на Python. Что именно вам нужно сделать?'" 659 | ] 660 | }, 661 | "execution_count": 16, 662 | "metadata": {}, 663 | "output_type": "execute_result" 664 | } 665 | ], 666 | "source": [ 667 | "# так же можно указать ключ response и в аутпуте получим только ответ модели\n", 668 | "conversation_bufwin_mem.invoke(input=\"Сможешь помочь мне в написании кода на Python?\")['response']" 669 | ] 670 | }, 671 | { 672 | "cell_type": "code", 673 | "execution_count": 19, 674 | "id": "2d7cb0dc-5adc-477b-a71f-2150f657ca35", 675 | "metadata": { 676 | "height": 30, 677 | "tags": [] 678 | }, 679 | "outputs": [ 680 | { 681 | "data": { 682 | "text/plain": [ 683 | "'Извините, но я не знаю, как вас зовут. Я только могу помочь с вопросами и задачами, связанными с кодированием на Python.'" 684 | ] 685 | }, 686 | "execution_count": 19, 687 | "metadata": {}, 688 | "output_type": "execute_result" 689 | } 690 | ], 691 | "source": [ 692 | "# Видим, что при k=1 первый диалог с именем не сохранился и модель не может ответить\n", 693 | "conversation_bufwin_mem.invoke(input=\"Как меня зовут?\")['response']" 694 | ] 695 | }, 696 | { 697 | "cell_type": "code", 698 | "execution_count": 14, 699 | "id": "88cee7bf-2d1d-475c-a603-53a2e4f3eb38", 700 | "metadata": { 701 | "height": 30, 702 | "tags": [] 703 | }, 704 | "outputs": [ 705 | { 706 | "data": { 707 | "application/vnd.jupyter.widget-view+json": { 708 | "model_id": "0d3d811545844cc48ae8668da8376f6f", 709 | "version_major": 2, 710 | "version_minor": 0 711 | }, 712 | "text/plain": [ 713 | "Downloading (…)olve/main/vocab.json: 0%| | 0.00/1.04M [00:00 🗜🗣 `ConversationSummaryMemory` - сохраняет \"смысл\"\n", 793 | "\n", 794 | "
\n", 795 | "\n", 796 | "Этот вид памяти суммаризует историю разговора перед передачей её в параметр `history`. Таким образом, можно сократить объем текста, обрабатываемого моделью и тратить меньше токенов." 797 | ] 798 | }, 799 | { 800 | "cell_type": "code", 801 | "execution_count": 4, 802 | "id": "92388461-084d-4e4b-b7a6-f468f402765b", 803 | "metadata": { 804 | "tags": [] 805 | }, 806 | "outputs": [ 807 | { 808 | "name": "stdout", 809 | "output_type": "stream", 810 | "text": [ 811 | "Progressively summarize the lines of conversation provided, adding onto the previous summary returning a new summary.\n", 812 | "\n", 813 | "EXAMPLE\n", 814 | "Current summary:\n", 815 | "The human asks what the AI thinks of artificial intelligence. The AI thinks artificial intelligence is a force for good.\n", 816 | "\n", 817 | "New lines of conversation:\n", 818 | "Human: Why do you think artificial intelligence is a force for good?\n", 819 | "AI: Because artificial intelligence will help humans reach their full potential.\n", 820 | "\n", 821 | "New summary:\n", 822 | "The human asks what the AI thinks of artificial intelligence. The AI thinks artificial intelligence is a force for good because it will help humans reach their full potential.\n", 823 | "END OF EXAMPLE\n", 824 | "\n", 825 | "Current summary:\n", 826 | "{summary}\n", 827 | "\n", 828 | "New lines of conversation:\n", 829 | "{new_lines}\n", 830 | "\n", 831 | "New summary:\n" 832 | ] 833 | } 834 | ], 835 | "source": [ 836 | "from langchain.chains.conversation.memory import ConversationSummaryMemory\n", 837 | "\n", 838 | "# Здесь тоже подаём модель, так как она необходима для суммаризации текста(не обязательно использовать ChatGPT)\n", 839 | "memory = ConversationSummaryMemory(llm=llm)\n", 840 | "\n", 841 | "conversation_sum_mem = ConversationChain(\n", 842 | " llm=llm,\n", 843 | " memory=memory\n", 844 | ")\n", 845 | "\n", 846 | "# посмотрим как поменялся шаблон для промпта\n", 847 | "print(conversation_sum_mem.memory.prompt.template)" 848 | ] 849 | }, 850 | { 851 | "cell_type": "markdown", 852 | "id": "1ab4055e-66a9-4e08-afc8-1e9cd0e8808e", 853 | "metadata": {}, 854 | "source": [ 855 | "
\n", 856 | " \n", 857 | "Теперь у нас появляется этап предобработки истории. На вход LLM мы подаем предыдущую историю (в виде `summary`), добавляем к ней текущий вывод модели (`new_lines`) и получаем новое состояние `summary`." 858 | ] 859 | }, 860 | { 861 | "cell_type": "code", 862 | "execution_count": 5, 863 | "id": "c70a45b0-c78f-48ac-936e-38ac6f3cdd02", 864 | "metadata": { 865 | "tags": [] 866 | }, 867 | "outputs": [ 868 | { 869 | "data": { 870 | "text/plain": [ 871 | "{'input': 'Привет, ChatGPT! Меня зовут Иван. Как дела?',\n", 872 | " 'history': '',\n", 873 | " 'response': 'Привет, Иван! Я ChatGPT, и мне очень хорошо! Я всегда готов общаться и помогать тебе. Чем могу помочь сегодня?'}" 874 | ] 875 | }, 876 | "execution_count": 5, 877 | "metadata": {}, 878 | "output_type": "execute_result" 879 | } 880 | ], 881 | "source": [ 882 | "conversation_sum_mem.invoke(\"Привет, ChatGPT! Меня зовут Иван. Как дела?\")" 883 | ] 884 | }, 885 | { 886 | "cell_type": "code", 887 | "execution_count": 6, 888 | "id": "94232c61-0dc2-48e6-8f2e-17d6c80785b2", 889 | "metadata": { 890 | "tags": [] 891 | }, 892 | "outputs": [ 893 | { 894 | "data": { 895 | "text/plain": [ 896 | "{'input': 'Сможешь помочь мне в написании кода на Python?',\n", 897 | " 'history': 'The human greets ChatGPT and introduces themselves as Ivan. ChatGPT responds that it is doing well and is always ready to communicate and help. It asks how it can assist Ivan today.',\n", 898 | " 'response': 'Конечно, я готов помочь в написании кода на Python! Расскажи мне, с чем именно тебе нужно помощь.'}" 899 | ] 900 | }, 901 | "execution_count": 6, 902 | "metadata": {}, 903 | "output_type": "execute_result" 904 | } 905 | ], 906 | "source": [ 907 | "conversation_sum_mem.invoke(\"Сможешь помочь мне в написании кода на Python?\")" 908 | ] 909 | }, 910 | { 911 | "cell_type": "markdown", 912 | "id": "73e087ee-4e92-4034-b459-218ed6b4a0fb", 913 | "metadata": { 914 | "tags": [] 915 | }, 916 | "source": [ 917 | "
\n", 918 | "\n", 919 | "Видим в `history`, суммаризованый предыдущий диалог уже на английском" 920 | ] 921 | }, 922 | { 923 | "cell_type": "code", 924 | "execution_count": 7, 925 | "id": "05326ec3-9c55-4d75-93a3-7ba16fca54c5", 926 | "metadata": { 927 | "tags": [] 928 | }, 929 | "outputs": [ 930 | { 931 | "data": { 932 | "text/plain": [ 933 | "{'input': \"Как вывести на экран 'Hello, world!' ?\",\n", 934 | " 'history': 'The human greets ChatGPT and introduces themselves as Ivan. ChatGPT responds that it is always ready to communicate and help. It asks how it can assist Ivan today. Ivan asks if ChatGPT can help him with writing Python code. ChatGPT enthusiastically agrees and asks Ivan to tell it specifically what he needs help with.',\n", 935 | " 'response': \"Привет, Иван! Чтобы вывести на экран 'Hello, world!' на языке Python, вам нужно использовать функцию print(). Просто напишите print('Hello, world!') и запустите код. Это выведет фразу 'Hello, world!' на экран. Если у вас возникнут еще вопросы или если вам нужна помощь с другим кодом, пожалуйста, сообщите мне.\"}" 936 | ] 937 | }, 938 | "execution_count": 7, 939 | "metadata": {}, 940 | "output_type": "execute_result" 941 | } 942 | ], 943 | "source": [ 944 | "conversation_sum_mem.invoke(\"Как вывести на экран 'Hello, world!' ?\")" 945 | ] 946 | }, 947 | { 948 | "cell_type": "markdown", 949 | "id": "55034146-01aa-4ae0-91fc-20f8decd6593", 950 | "metadata": {}, 951 | "source": [ 952 | "
\n", 953 | " \n", 954 | "### Другие виды памяти:\n", 955 | "\n", 956 | "* `ConversationSummaryBufferMemory` - позволяет задать окно (в токенах), в рамках которого мы сохраняем диалоги в неизменной форме, а при превышении - суммаризируем.\n", 957 | "* `ConversationKGMemory` - использует граф знаний для сохранения памяти.\n", 958 | "* `ConversationEntityMemory` - сохраняет в памяти знания об определенном объекте." 959 | ] 960 | }, 961 | { 962 | "cell_type": "markdown", 963 | "id": "12cb6a46-c81b-4ea1-9d26-b5ac6d4e5ff8", 964 | "metadata": {}, 965 | "source": [ 966 | "#

🔗 Chains 🔗 - продолжение следует...

" 967 | ] 968 | } 969 | ], 970 | "metadata": { 971 | "kernelspec": { 972 | "display_name": "cv", 973 | "language": "python", 974 | "name": "python3" 975 | }, 976 | "language_info": { 977 | "codemirror_mode": { 978 | "name": "ipython", 979 | "version": 3 980 | }, 981 | "file_extension": ".py", 982 | "mimetype": "text/x-python", 983 | "name": "python", 984 | "nbconvert_exporter": "python", 985 | "pygments_lexer": "ipython3", 986 | "version": "3.10.12" 987 | } 988 | }, 989 | "nbformat": 4, 990 | "nbformat_minor": 5 991 | } 992 | -------------------------------------------------------------------------------- /notebooks/M5_2_Dataset_prepare.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "0151820b-1ed6-431d-8a87-23e24ad2dcde", 6 | "metadata": {}, 7 | "source": [ 8 | "#
Готовим данные для файнтюнинга LLM. 🦙
\n", 9 | "\n", 10 | "\n", 11 | "\n", 12 | "В этом ноутбуке подготовим датасет для файнтюнинга LLM и загрузим его на `HuggingFace`.
\n", 13 | "\n", 14 | "В качестве источника данных скачаем все посты из Telegram-канала [Datafeeling](https://t.me/datafeeling), через который многие нашли этот курс. В дальнейшем, с помощью этого датасета зафайнтюним модель писать посты в стиле Алерона.
\n", 15 | "\n", 16 | "**Чтобы скачать все посты любого публичного TG-канала:**\n", 17 | "* в десктоп приложении Telegram переходим к канал\n", 18 | "* нажимаем три точки\n", 19 | "* выбираем - \"Экспорт истории чата\"\n", 20 | "* там выбираем формат (HTML или json), путь куда сохраняем и какой контент канала хотим скачать\n", 21 | "* получаем все посты в одном файле (в нашем случае json)" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 22, 27 | "id": "c3e52fc5-ecb9-4a92-a943-afb96ac784c4", 28 | "metadata": {}, 29 | "outputs": [ 30 | { 31 | "name": "stdout", 32 | "output_type": "stream", 33 | "text": [ 34 | "\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n", 35 | "sphinx-rtd-theme 2.0.0 requires docutils<0.21, but you have docutils 0.21.2 which is incompatible.\n", 36 | "mxnet 1.9.1 requires graphviz<0.9.0,>=0.8.1, but you have graphviz 0.20.3 which is incompatible.\n", 37 | "bentoml 0.13.2+6.g2dc5913c requires sqlalchemy<1.4.0,>=1.3.0, but you have sqlalchemy 2.0.29 which is incompatible.\n", 38 | "anomalib 0.7.0 requires pytorch-lightning<1.10.0,>=1.7.0, but you have pytorch-lightning 2.1.4 which is incompatible.\u001b[0m\u001b[31m\n", 39 | "\u001b[0m" 40 | ] 41 | } 42 | ], 43 | "source": [ 44 | "!pip install datasets langchain langchain-openai openai -q" 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "execution_count": null, 50 | "id": "734683a0-e9ad-4e46-9537-9e4fc2e1235a", 51 | "metadata": { 52 | "jupyter": { 53 | "source_hidden": true 54 | } 55 | }, 56 | "outputs": [], 57 | "source": [ 58 | "# Для работы в колабе загрузите наш скрипт для использования ChatGPT с ключом курса и необходимые файлы!\n", 59 | "# !mkdir ../data/\n", 60 | "# !wget -P ../data https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/main/data/result.json\n", 61 | "# !wget https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/main/notebooks/utils.py" 62 | ] 63 | }, 64 | { 65 | "cell_type": "code", 66 | "execution_count": 3, 67 | "id": "56e5b2d5-8c77-465a-9cef-2f58f120f4e0", 68 | "metadata": {}, 69 | "outputs": [], 70 | "source": [ 71 | "import os\n", 72 | "from getpass import getpass\n", 73 | "import pandas as pd\n", 74 | "import json\n", 75 | "import warnings\n", 76 | "warnings.filterwarnings('ignore')" 77 | ] 78 | }, 79 | { 80 | "cell_type": "code", 81 | "execution_count": 10, 82 | "id": "6cf8eb32-e0b4-4c68-9a15-8c35102f2033", 83 | "metadata": {}, 84 | "outputs": [ 85 | { 86 | "data": { 87 | "text/plain": [ 88 | "{'id': 3,\n", 89 | " 'type': 'message',\n", 90 | " 'date': '2021-03-21T20:26:01',\n", 91 | " 'date_unixtime': '1616343961',\n", 92 | " 'edited': '2021-04-11T00:37:28',\n", 93 | " 'edited_unixtime': '1618087048',\n", 94 | " 'from': '🏆 Data Feeling 🤹',\n", 95 | " 'from_id': 'channel1457597091',\n", 96 | " 'text': 'Всем привет!\\n\\nРешил запустить свой канал. Буду рассказывать здесь про свой опыт в Data Science и лайфхаки',\n", 97 | " 'text_entities': [{'type': 'plain',\n", 98 | " 'text': 'Всем привет!\\n\\nРешил запустить свой канал. Буду рассказывать здесь про свой опыт в Data Science и лайфхаки'}]}" 99 | ] 100 | }, 101 | "execution_count": 10, 102 | "metadata": {}, 103 | "output_type": "execute_result" 104 | } 105 | ], 106 | "source": [ 107 | "# указываем путь к файлу, скаченному из телеграма\n", 108 | "js_path = '../data/result.json'\n", 109 | "\n", 110 | "# Load the JSON file\n", 111 | "with open(js_path, 'r') as file:\n", 112 | " data = json.load(file)\n", 113 | "\n", 114 | "# посмотрим на первое сообщение\n", 115 | "data['messages'][2]" 116 | ] 117 | }, 118 | { 119 | "cell_type": "markdown", 120 | "id": "0ab52752-9b8f-4216-b0d8-9cc63d0b908d", 121 | "metadata": {}, 122 | "source": [ 123 | "
\n", 124 | " \n", 125 | "Видим, что помимо текста поста в сообщениях содержится ещё много дополнительной информации. Для наших целей извлечём только тексты." 126 | ] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "execution_count": 11, 131 | "id": "cf567da8-902c-4090-b244-1ac707dc8680", 132 | "metadata": {}, 133 | "outputs": [], 134 | "source": [ 135 | "txt = []\n", 136 | "for message in data['messages']:\n", 137 | " if isinstance(message['text'], str):\n", 138 | " txt.append(message['text'])\n", 139 | " else:\n", 140 | " temp_txt = ''\n", 141 | " for m in message['text']:\n", 142 | " if isinstance(m, str):\n", 143 | " temp_txt += m\n", 144 | " else:\n", 145 | " if isinstance(m, dict) and 'text' in m.keys():\n", 146 | " temp_txt += m['text']\n", 147 | " txt.append(temp_txt)" 148 | ] 149 | }, 150 | { 151 | "cell_type": "code", 152 | "execution_count": 16, 153 | "id": "1a08b269-bb9e-4277-b457-78272c33ca69", 154 | "metadata": {}, 155 | "outputs": [ 156 | { 157 | "data": { 158 | "text/html": [ 159 | "
\n", 160 | "\n", 173 | "\n", 174 | " \n", 175 | " \n", 176 | " \n", 177 | " \n", 178 | " \n", 179 | " \n", 180 | " \n", 181 | " \n", 182 | " \n", 183 | " \n", 184 | " \n", 185 | " \n", 186 | " \n", 187 | " \n", 188 | " \n", 189 | " \n", 190 | " \n", 191 | " \n", 192 | " \n", 193 | " \n", 194 | " \n", 195 | " \n", 196 | " \n", 197 | " \n", 198 | " \n", 199 | " \n", 200 | " \n", 201 | " \n", 202 | "
text
0
1
2Всем привет!\\n\\nРешил запустить свой канал. Бу...
3Когда начинаешь погружаться в DS - начинаешь р...
4#лайфхаки\\nПоймал себя на периодическом подгля...
\n", 203 | "
" 204 | ], 205 | "text/plain": [ 206 | " text\n", 207 | "0 \n", 208 | "1 \n", 209 | "2 Всем привет!\\n\\nРешил запустить свой канал. Бу...\n", 210 | "3 Когда начинаешь погружаться в DS - начинаешь р...\n", 211 | "4 #лайфхаки\\nПоймал себя на периодическом подгля..." 212 | ] 213 | }, 214 | "execution_count": 16, 215 | "metadata": {}, 216 | "output_type": "execute_result" 217 | } 218 | ], 219 | "source": [ 220 | "df = pd.DataFrame({\"text\": txt})\n", 221 | "df.head()" 222 | ] 223 | }, 224 | { 225 | "cell_type": "markdown", 226 | "id": "10d805b1-bc70-4ddb-a1a9-d5f378c3e7f7", 227 | "metadata": {}, 228 | "source": [ 229 | "
\n", 230 | " \n", 231 | "Видим, что есть посты без текстов - видео или картинки.
\n", 232 | "Преобразуем датасет в нужный формат и почистим от пропусков." 233 | ] 234 | }, 235 | { 236 | "cell_type": "code", 237 | "execution_count": 18, 238 | "id": "04a42e1a-978d-4700-8d80-3d93d47b8eea", 239 | "metadata": {}, 240 | "outputs": [ 241 | { 242 | "data": { 243 | "text/html": [ 244 | "
\n", 245 | "\n", 258 | "\n", 259 | " \n", 260 | " \n", 261 | " \n", 262 | " \n", 263 | " \n", 264 | " \n", 265 | " \n", 266 | " \n", 267 | " \n", 268 | " \n", 269 | " \n", 270 | " \n", 271 | " \n", 272 | " \n", 273 | " \n", 274 | " \n", 275 | " \n", 276 | " \n", 277 | " \n", 278 | " \n", 279 | " \n", 280 | " \n", 281 | " \n", 282 | " \n", 283 | " \n", 284 | " \n", 285 | " \n", 286 | " \n", 287 | " \n", 288 | " \n", 289 | " \n", 290 | " \n", 291 | " \n", 292 | " \n", 293 | " \n", 294 | " \n", 295 | " \n", 296 | " \n", 297 | " \n", 298 | " \n", 299 | "
InstructionInputResponse
0Write a post on the following topicВсем привет!\\n\\nРешил запустить свой канал. Бу...
1Write a post on the following topicКогда начинаешь погружаться в DS - начинаешь р...
2Write a post on the following topic#лайфхаки\\nПоймал себя на периодическом подгля...
3Write a post on the following topicSpeed up'ал, speed up'аю и буду speed up'ать с...
4Write a post on the following topicЗа этот месяц раз 5 услышал слово \"экстраполяц...
\n", 300 | "
" 301 | ], 302 | "text/plain": [ 303 | " Instruction Input \\\n", 304 | "0 Write a post on the following topic \n", 305 | "1 Write a post on the following topic \n", 306 | "2 Write a post on the following topic \n", 307 | "3 Write a post on the following topic \n", 308 | "4 Write a post on the following topic \n", 309 | "\n", 310 | " Response \n", 311 | "0 Всем привет!\\n\\nРешил запустить свой канал. Бу... \n", 312 | "1 Когда начинаешь погружаться в DS - начинаешь р... \n", 313 | "2 #лайфхаки\\nПоймал себя на периодическом подгля... \n", 314 | "3 Speed up'ал, speed up'аю и буду speed up'ать с... \n", 315 | "4 За этот месяц раз 5 услышал слово \"экстраполяц... " 316 | ] 317 | }, 318 | "execution_count": 18, 319 | "metadata": {}, 320 | "output_type": "execute_result" 321 | } 322 | ], 323 | "source": [ 324 | "df = pd.DataFrame({\n", 325 | " 'Instruction': 'Write a post on the following topic', # Инструкция будет везде одинаковая\n", 326 | " 'Input': '', # поле с темой поста пока оставим пустым\n", 327 | " 'Response': [t for t in txt if len(t) != 0] # в Response записываем текст поста и убираем пустые строки\n", 328 | "})\n", 329 | "\n", 330 | "df.head()" 331 | ] 332 | }, 333 | { 334 | "cell_type": "code", 335 | "execution_count": 19, 336 | "id": "ee350083-79c0-46f2-8dfb-65b1062bd905", 337 | "metadata": {}, 338 | "outputs": [ 339 | { 340 | "name": "stdout", 341 | "output_type": "stream", 342 | "text": [ 343 | "\n", 344 | "RangeIndex: 587 entries, 0 to 586\n", 345 | "Data columns (total 3 columns):\n", 346 | " # Column Non-Null Count Dtype \n", 347 | "--- ------ -------------- ----- \n", 348 | " 0 Instruction 587 non-null object\n", 349 | " 1 Input 587 non-null object\n", 350 | " 2 Response 587 non-null object\n", 351 | "dtypes: object(3)\n", 352 | "memory usage: 13.9+ KB\n" 353 | ] 354 | } 355 | ], 356 | "source": [ 357 | "# Получилось 587 постов с текстом.\n", 358 | "df.info()" 359 | ] 360 | }, 361 | { 362 | "cell_type": "markdown", 363 | "id": "2aa24ae9-b679-4321-9fc8-4a38b11515a8", 364 | "metadata": {}, 365 | "source": [ 366 | "## Определяем тематику поста с помощью ChatGPT 🤖\n", 367 | "\n", 368 | "Чтобы самим не заполнять поле input и не читать все 580 сообщений, определяя тему - попросим ЛЛМ сделать это за нас." 369 | ] 370 | }, 371 | { 372 | "cell_type": "code", 373 | "execution_count": 22, 374 | "id": "c7baf94a-00d7-42c2-8429-69bedaa51704", 375 | "metadata": {}, 376 | "outputs": [ 377 | { 378 | "name": "stdin", 379 | "output_type": "stream", 380 | "text": [ 381 | "Введите ваш OpenAI API ключ ········\n" 382 | ] 383 | } 384 | ], 385 | "source": [ 386 | "from utils import ChatOpenAI\n", 387 | "\n", 388 | "#course_api_key= \"Введите ваш OpenAI API ключ\"\n", 389 | "course_api_key = getpass(prompt='Введите ваш OpenAI API ключ')\n", 390 | "\n", 391 | "# инициализируем языковую модель\n", 392 | "llm = ChatOpenAI(temperature=0.0, course_api_key=course_api_key)" 393 | ] 394 | }, 395 | { 396 | "cell_type": "code", 397 | "execution_count": 35, 398 | "id": "a74034dd-2b08-4d27-bb02-3346167ef88f", 399 | "metadata": {}, 400 | "outputs": [ 401 | { 402 | "name": "stderr", 403 | "output_type": "stream", 404 | "text": [ 405 | "100%|██████████| 587/587 [07:25<00:00, 1.32it/s]\n" 406 | ] 407 | } 408 | ], 409 | "source": [ 410 | "from tqdm import tqdm\n", 411 | "tqdm.pandas()\n", 412 | "\n", 413 | "# Функция для определения тематики поста. Примени её ко всему датасету.\n", 414 | "def topic_extractor(text):\n", 415 | " \n", 416 | " answer = llm.invoke(f'Extract a phrase that best describes the topic of the following post. \\n Post: {text}')\n", 417 | " return str(answer.content)\n", 418 | "\n", 419 | "df['Input'] = df['Response'].progress_apply(topic_extractor)" 420 | ] 421 | }, 422 | { 423 | "cell_type": "code", 424 | "execution_count": 20, 425 | "id": "d539446e-1d83-43d0-a25b-d947fe4e4546", 426 | "metadata": {}, 427 | "outputs": [ 428 | { 429 | "data": { 430 | "text/html": [ 431 | "
\n", 432 | "\n", 445 | "\n", 446 | " \n", 447 | " \n", 448 | " \n", 449 | " \n", 450 | " \n", 451 | " \n", 452 | " \n", 453 | " \n", 454 | " \n", 455 | " \n", 456 | " \n", 457 | " \n", 458 | " \n", 459 | " \n", 460 | " \n", 461 | " \n", 462 | " \n", 463 | " \n", 464 | " \n", 465 | " \n", 466 | " \n", 467 | " \n", 468 | " \n", 469 | " \n", 470 | " \n", 471 | " \n", 472 | " \n", 473 | " \n", 474 | " \n", 475 | " \n", 476 | " \n", 477 | " \n", 478 | " \n", 479 | " \n", 480 | " \n", 481 | " \n", 482 | " \n", 483 | " \n", 484 | " \n", 485 | " \n", 486 | "
InstructionInputResponse
0Write a post on the following topicЗапуск канала о Data ScienceВсем привет!\\n\\nРешил запустить свой канал. Бу...
1Write a post on the following topicПростые примеры кода для новых методов/алгоритмовКогда начинаешь погружаться в DS - начинаешь р...
2Write a post on the following topicПолезные расширения для работы с табличными да...#лайфхаки\\nПоймал себя на периодическом подгля...
3Write a post on the following topicWays to speed up Pytorch training on KaggleSpeed up'ал, speed up'аю и буду speed up'ать с...
4Write a post on the following topicИнтерпретация моделей в машинном обученииЗа этот месяц раз 5 услышал слово \"экстраполяц...
\n", 487 | "
" 488 | ], 489 | "text/plain": [ 490 | " Instruction \\\n", 491 | "0 Write a post on the following topic \n", 492 | "1 Write a post on the following topic \n", 493 | "2 Write a post on the following topic \n", 494 | "3 Write a post on the following topic \n", 495 | "4 Write a post on the following topic \n", 496 | "\n", 497 | " Input \\\n", 498 | "0 Запуск канала о Data Science \n", 499 | "1 Простые примеры кода для новых методов/алгоритмов \n", 500 | "2 Полезные расширения для работы с табличными да... \n", 501 | "3 Ways to speed up Pytorch training on Kaggle \n", 502 | "4 Интерпретация моделей в машинном обучении \n", 503 | "\n", 504 | " Response \n", 505 | "0 Всем привет!\\n\\nРешил запустить свой канал. Бу... \n", 506 | "1 Когда начинаешь погружаться в DS - начинаешь р... \n", 507 | "2 #лайфхаки\\nПоймал себя на периодическом подгля... \n", 508 | "3 Speed up'ал, speed up'аю и буду speed up'ать с... \n", 509 | "4 За этот месяц раз 5 услышал слово \"экстраполяц... " 510 | ] 511 | }, 512 | "execution_count": 20, 513 | "metadata": {}, 514 | "output_type": "execute_result" 515 | } 516 | ], 517 | "source": [ 518 | "df.head()" 519 | ] 520 | }, 521 | { 522 | "cell_type": "markdown", 523 | "id": "9ae95235-8f78-48db-af38-32cab49f0695", 524 | "metadata": {}, 525 | "source": [ 526 | "
\n", 527 | " \n", 528 | "Видим, что модель отлично справилась с задачей - тематика хорошо определена." 529 | ] 530 | }, 531 | { 532 | "cell_type": "code", 533 | "execution_count": 36, 534 | "id": "f844bc06-0623-43d0-9130-66551a097081", 535 | "metadata": {}, 536 | "outputs": [], 537 | "source": [ 538 | "# Сохраняем датасет\n", 539 | "df.to_csv('../data/prepared_dataset.csv', index=False)" 540 | ] 541 | }, 542 | { 543 | "cell_type": "markdown", 544 | "id": "812e95c4-56c1-49cf-8f6f-f80c853fdf13", 545 | "metadata": {}, 546 | "source": [ 547 | "# Загружаем датасет на HuggingFace 🤗" 548 | ] 549 | }, 550 | { 551 | "cell_type": "markdown", 552 | "id": "e01a4805-7b7c-4db7-b3e9-0d86ce0e599b", 553 | "metadata": {}, 554 | "source": [ 555 | "
\n", 556 | " \n", 557 | "Теперь переходим на [HuggingFace](https://huggingface.co) и создаем новый датасет, затем в него подгружаем получившийся файл.
\n", 558 | "Теперь датасет доступен всем по ссылке: https://huggingface.co/datasets/Ivanich/datafeeling_posts" 559 | ] 560 | }, 561 | { 562 | "cell_type": "code", 563 | "execution_count": 23, 564 | "id": "e00a298c-5831-4068-bc8e-e5cb9b1380f4", 565 | "metadata": {}, 566 | "outputs": [ 567 | { 568 | "data": { 569 | "application/vnd.jupyter.widget-view+json": { 570 | "model_id": "aa6557d3dc84484a82a3ede5a7cb64f5", 571 | "version_major": 2, 572 | "version_minor": 0 573 | }, 574 | "text/plain": [ 575 | "Downloading readme: 0%| | 0.00/157 [00:00'" 188 | ] 189 | }, 190 | { 191 | "cell_type": "markdown", 192 | "metadata": {}, 193 | "source": [ 194 | "## LoRA adapter" 195 | ] 196 | }, 197 | { 198 | "cell_type": "code", 199 | "execution_count": null, 200 | "metadata": { 201 | "execution": { 202 | "iopub.execute_input": "2024-07-31T19:23:18.406871Z", 203 | "iopub.status.busy": "2024-07-31T19:23:18.406587Z", 204 | "iopub.status.idle": "2024-07-31T19:23:19.566904Z", 205 | "shell.execute_reply": "2024-07-31T19:23:19.565881Z", 206 | "shell.execute_reply.started": "2024-07-31T19:23:18.406847Z" 207 | } 208 | }, 209 | "outputs": [], 210 | "source": [ 211 | "# LoRA config\n", 212 | "peft_config = LoraConfig(\n", 213 | " r=16,\n", 214 | " lora_alpha=32,\n", 215 | " lora_dropout=0.05,\n", 216 | " bias=\"none\",\n", 217 | " task_type=\"CAUSAL_LM\",\n", 218 | " target_modules=['up_proj', 'down_proj', 'gate_proj', 'k_proj', 'q_proj', 'v_proj', 'o_proj']\n", 219 | ")\n", 220 | "model = get_peft_model(model, peft_config)" 221 | ] 222 | }, 223 | { 224 | "cell_type": "markdown", 225 | "metadata": {}, 226 | "source": [ 227 | "# Data" 228 | ] 229 | }, 230 | { 231 | "cell_type": "markdown", 232 | "metadata": {}, 233 | "source": [ 234 | "## Load" 235 | ] 236 | }, 237 | { 238 | "cell_type": "code", 239 | "execution_count": null, 240 | "metadata": { 241 | "execution": { 242 | "iopub.execute_input": "2024-07-31T19:23:19.568419Z", 243 | "iopub.status.busy": "2024-07-31T19:23:19.568121Z", 244 | "iopub.status.idle": "2024-07-31T19:23:24.466352Z", 245 | "shell.execute_reply": "2024-07-31T19:23:24.465507Z", 246 | "shell.execute_reply.started": "2024-07-31T19:23:19.568394Z" 247 | } 248 | }, 249 | "outputs": [], 250 | "source": [ 251 | "dataset = load_dataset(cfg.dataset_name, split=\"all\")" 252 | ] 253 | }, 254 | { 255 | "cell_type": "markdown", 256 | "metadata": {}, 257 | "source": [ 258 | "## Format to chat " 259 | ] 260 | }, 261 | { 262 | "cell_type": "code", 263 | "execution_count": null, 264 | "metadata": { 265 | "execution": { 266 | "iopub.execute_input": "2024-07-31T19:23:24.467754Z", 267 | "iopub.status.busy": "2024-07-31T19:23:24.467426Z", 268 | "iopub.status.idle": "2024-07-31T19:23:24.473839Z", 269 | "shell.execute_reply": "2024-07-31T19:23:24.472918Z", 270 | "shell.execute_reply.started": "2024-07-31T19:23:24.467728Z" 271 | } 272 | }, 273 | "outputs": [], 274 | "source": [ 275 | "def format_chat_template(row):\n", 276 | " row_json = [{\"role\": \"user\", \"content\": row[\"Patient\"]},\n", 277 | " {\"role\": \"assistant\", \"content\": row[\"Doctor\"]}]\n", 278 | " row[\"text\"] = tokenizer.apply_chat_template(row_json, tokenize=False)\n", 279 | " return row" 280 | ] 281 | }, 282 | { 283 | "cell_type": "code", 284 | "execution_count": null, 285 | "metadata": { 286 | "execution": { 287 | "iopub.execute_input": "2024-07-31T19:23:24.478016Z", 288 | "iopub.status.busy": "2024-07-31T19:23:24.477695Z", 289 | "iopub.status.idle": "2024-07-31T19:23:39.357867Z", 290 | "shell.execute_reply": "2024-07-31T19:23:39.356931Z", 291 | "shell.execute_reply.started": "2024-07-31T19:23:24.477991Z" 292 | } 293 | }, 294 | "outputs": [], 295 | "source": [ 296 | "dataset = dataset.map(\n", 297 | " format_chat_template,\n", 298 | " num_proc=4,\n", 299 | ")" 300 | ] 301 | }, 302 | { 303 | "cell_type": "markdown", 304 | "metadata": {}, 305 | "source": [ 306 | "## Select only part" 307 | ] 308 | }, 309 | { 310 | "cell_type": "code", 311 | "execution_count": null, 312 | "metadata": { 313 | "execution": { 314 | "iopub.execute_input": "2024-07-31T19:23:39.359682Z", 315 | "iopub.status.busy": "2024-07-31T19:23:39.359332Z", 316 | "iopub.status.idle": "2024-07-31T19:23:41.449434Z", 317 | "shell.execute_reply": "2024-07-31T19:23:41.448661Z", 318 | "shell.execute_reply.started": "2024-07-31T19:23:39.35965Z" 319 | } 320 | }, 321 | "outputs": [], 322 | "source": [ 323 | "dataset_sh = dataset.shuffle(seed=2024).select(range(10_000))" 324 | ] 325 | }, 326 | { 327 | "cell_type": "code", 328 | "execution_count": null, 329 | "metadata": { 330 | "execution": { 331 | "iopub.execute_input": "2024-07-31T19:23:41.451005Z", 332 | "iopub.status.busy": "2024-07-31T19:23:41.450648Z", 333 | "iopub.status.idle": "2024-07-31T19:23:41.484003Z", 334 | "shell.execute_reply": "2024-07-31T19:23:41.482915Z", 335 | "shell.execute_reply.started": "2024-07-31T19:23:41.450974Z" 336 | } 337 | }, 338 | "outputs": [], 339 | "source": [ 340 | "dataset_sh = dataset_sh.train_test_split(0.1)\n", 341 | "dataset_sh" 342 | ] 343 | }, 344 | { 345 | "cell_type": "markdown", 346 | "metadata": {}, 347 | "source": [ 348 | "# Train model" 349 | ] 350 | }, 351 | { 352 | "cell_type": "markdown", 353 | "metadata": {}, 354 | "source": [ 355 | "## Training arguments" 356 | ] 357 | }, 358 | { 359 | "cell_type": "code", 360 | "execution_count": null, 361 | "metadata": { 362 | "execution": { 363 | "iopub.execute_input": "2024-07-31T19:40:20.141299Z", 364 | "iopub.status.busy": "2024-07-31T19:40:20.1409Z", 365 | "iopub.status.idle": "2024-07-31T19:40:20.182873Z", 366 | "shell.execute_reply": "2024-07-31T19:40:20.182009Z", 367 | "shell.execute_reply.started": "2024-07-31T19:40:20.141268Z" 368 | } 369 | }, 370 | "outputs": [], 371 | "source": [ 372 | "training_arguments = TrainingArguments(\n", 373 | " output_dir=cfg.new_model,\n", 374 | " per_device_train_batch_size=1,\n", 375 | " per_device_eval_batch_size=4,\n", 376 | " gradient_accumulation_steps=2,\n", 377 | " optim=\"paged_adamw_32bit\",\n", 378 | "# num_train_epochs=1,\n", 379 | " max_steps=500,\n", 380 | " eval_strategy=\"steps\",\n", 381 | " eval_steps=500,\n", 382 | " logging_steps=100,\n", 383 | " warmup_steps=10,\n", 384 | " logging_strategy=\"steps\",\n", 385 | " learning_rate=2e-4,\n", 386 | " fp16=False,\n", 387 | " bf16=True,\n", 388 | " group_by_length=True,\n", 389 | " report_to=\"wandb\",\n", 390 | " run_name=\"Llama-3.1-medicine\",\n", 391 | ")" 392 | ] 393 | }, 394 | { 395 | "cell_type": "markdown", 396 | "metadata": {}, 397 | "source": [ 398 | "## Train model" 399 | ] 400 | }, 401 | { 402 | "cell_type": "code", 403 | "execution_count": null, 404 | "metadata": { 405 | "execution": { 406 | "iopub.execute_input": "2024-07-31T19:40:21.439957Z", 407 | "iopub.status.busy": "2024-07-31T19:40:21.439288Z", 408 | "iopub.status.idle": "2024-07-31T19:40:27.98408Z", 409 | "shell.execute_reply": "2024-07-31T19:40:27.983305Z", 410 | "shell.execute_reply.started": "2024-07-31T19:40:21.439924Z" 411 | } 412 | }, 413 | "outputs": [], 414 | "source": [ 415 | "trainer = SFTTrainer(\n", 416 | " model=model,\n", 417 | " train_dataset=dataset_sh[\"train\"],\n", 418 | " eval_dataset=dataset_sh[\"test\"],\n", 419 | " peft_config=peft_config,\n", 420 | " max_seq_length=512,\n", 421 | " dataset_text_field=\"text\",\n", 422 | " tokenizer=tokenizer,\n", 423 | " args=training_arguments,\n", 424 | " packing= False,\n", 425 | ")" 426 | ] 427 | }, 428 | { 429 | "cell_type": "code", 430 | "execution_count": null, 431 | "metadata": { 432 | "execution": { 433 | "iopub.execute_input": "2024-07-31T19:40:31.097638Z", 434 | "iopub.status.busy": "2024-07-31T19:40:31.097229Z", 435 | "iopub.status.idle": "2024-07-31T20:09:00.849422Z", 436 | "shell.execute_reply": "2024-07-31T20:09:00.847937Z", 437 | "shell.execute_reply.started": "2024-07-31T19:40:31.097607Z" 438 | } 439 | }, 440 | "outputs": [], 441 | "source": [ 442 | "trainer.train()" 443 | ] 444 | }, 445 | { 446 | "cell_type": "code", 447 | "execution_count": null, 448 | "metadata": { 449 | "execution": { 450 | "iopub.execute_input": "2024-07-31T20:09:40.932639Z", 451 | "iopub.status.busy": "2024-07-31T20:09:40.931936Z", 452 | "iopub.status.idle": "2024-07-31T20:10:11.058559Z", 453 | "shell.execute_reply": "2024-07-31T20:10:11.057552Z", 454 | "shell.execute_reply.started": "2024-07-31T20:09:40.932606Z" 455 | } 456 | }, 457 | "outputs": [], 458 | "source": [ 459 | "path_to_save = \"Llama-finetuned\"\n", 460 | "trainer.save_model(path_to_save)\n", 461 | "model.save_pretrained(path_to_save)\n", 462 | "tokenizer.save_pretrained(path_to_save)" 463 | ] 464 | }, 465 | { 466 | "cell_type": "code", 467 | "execution_count": null, 468 | "metadata": { 469 | "execution": { 470 | "iopub.execute_input": "2024-07-31T20:25:47.955124Z", 471 | "iopub.status.busy": "2024-07-31T20:25:47.954733Z", 472 | "iopub.status.idle": "2024-07-31T20:25:47.964991Z", 473 | "shell.execute_reply": "2024-07-31T20:25:47.963846Z", 474 | "shell.execute_reply.started": "2024-07-31T20:25:47.955095Z" 475 | } 476 | }, 477 | "outputs": [], 478 | "source": [ 479 | "del model, tokenizer, trainer" 480 | ] 481 | }, 482 | { 483 | "cell_type": "markdown", 484 | "metadata": {}, 485 | "source": [ 486 | "# Compare models" 487 | ] 488 | }, 489 | { 490 | "cell_type": "markdown", 491 | "metadata": {}, 492 | "source": [ 493 | "## Init casual LLM" 494 | ] 495 | }, 496 | { 497 | "cell_type": "code", 498 | "execution_count": null, 499 | "metadata": { 500 | "execution": { 501 | "iopub.execute_input": "2024-07-31T20:28:13.860754Z", 502 | "iopub.status.busy": "2024-07-31T20:28:13.859897Z", 503 | "iopub.status.idle": "2024-07-31T20:29:29.136779Z", 504 | "shell.execute_reply": "2024-07-31T20:29:29.135671Z", 505 | "shell.execute_reply.started": "2024-07-31T20:28:13.86072Z" 506 | } 507 | }, 508 | "outputs": [], 509 | "source": [ 510 | "# QLoRA config\n", 511 | "bnb_config = BitsAndBytesConfig(\n", 512 | " load_in_4bit=True,\n", 513 | " bnb_4bit_quant_type=\"nf4\",\n", 514 | " bnb_4bit_compute_dtype=cfg.torch_dtype,\n", 515 | " bnb_4bit_use_double_quant=True,\n", 516 | ")\n", 517 | "\n", 518 | "# Load model\n", 519 | "casual_model = AutoModelForCausalLM.from_pretrained(\n", 520 | " cfg.model_name,\n", 521 | " quantization_config=bnb_config,\n", 522 | "# device_map=\"auto\",\n", 523 | " attn_implementation=cfg.attn_implementation\n", 524 | ")\n", 525 | "\n", 526 | "tokenizer = tokenizer = AutoTokenizer.from_pretrained(cfg.model_name)\n", 527 | "tokenizer.padding_side = 'right'\n", 528 | "tokenizer.padding_token = '<|pad_token|>'" 529 | ] 530 | }, 531 | { 532 | "cell_type": "code", 533 | "execution_count": null, 534 | "metadata": { 535 | "execution": { 536 | "iopub.execute_input": "2024-07-31T20:29:29.13895Z", 537 | "iopub.status.busy": "2024-07-31T20:29:29.138645Z", 538 | "iopub.status.idle": "2024-07-31T20:29:29.198595Z", 539 | "shell.execute_reply": "2024-07-31T20:29:29.197438Z", 540 | "shell.execute_reply.started": "2024-07-31T20:29:29.138923Z" 541 | } 542 | }, 543 | "outputs": [], 544 | "source": [ 545 | "casual_model, tokenizer = setup_chat_format(casual_model, tokenizer)" 546 | ] 547 | }, 548 | { 549 | "cell_type": "markdown", 550 | "metadata": {}, 551 | "source": [ 552 | "## Get answers" 553 | ] 554 | }, 555 | { 556 | "cell_type": "code", 557 | "execution_count": null, 558 | "metadata": { 559 | "execution": { 560 | "iopub.execute_input": "2024-07-31T20:29:29.200105Z", 561 | "iopub.status.busy": "2024-07-31T20:29:29.19983Z", 562 | "iopub.status.idle": "2024-07-31T20:29:29.207428Z", 563 | "shell.execute_reply": "2024-07-31T20:29:29.206299Z", 564 | "shell.execute_reply.started": "2024-07-31T20:29:29.20008Z" 565 | } 566 | }, 567 | "outputs": [], 568 | "source": [ 569 | "def generate_answer(model, prompt):\n", 570 | " chat = [\n", 571 | " { \"role\": \"user\", \"content\": prompt },\n", 572 | " ]\n", 573 | " prompt = tokenizer.apply_chat_template(chat, tokenize=False, add_generation_prompt=True)\n", 574 | " inputs = tokenizer.encode(prompt, add_special_tokens=False, return_tensors=\"pt\")\n", 575 | " outputs = model.generate(input_ids=inputs.to(model.device), max_new_tokens=150)\n", 576 | "\n", 577 | " return(tokenizer.decode(outputs[0]))" 578 | ] 579 | }, 580 | { 581 | "cell_type": "markdown", 582 | "metadata": {}, 583 | "source": [ 584 | "# Comprasion" 585 | ] 586 | }, 587 | { 588 | "cell_type": "code", 589 | "execution_count": null, 590 | "metadata": { 591 | "execution": { 592 | "iopub.execute_input": "2024-07-31T20:29:36.89578Z", 593 | "iopub.status.busy": "2024-07-31T20:29:36.894921Z", 594 | "iopub.status.idle": "2024-07-31T20:29:36.901397Z", 595 | "shell.execute_reply": "2024-07-31T20:29:36.900326Z", 596 | "shell.execute_reply.started": "2024-07-31T20:29:36.895742Z" 597 | } 598 | }, 599 | "outputs": [], 600 | "source": [ 601 | "q1 = \"I have severe headaches help me please\"\n", 602 | "q2 = \"I have a suspiciously large mole. Could I have cancer? How can I determine this at home?\"\n", 603 | "q3 = \"What does abutment of the nerve root mean?\"" 604 | ] 605 | }, 606 | { 607 | "cell_type": "code", 608 | "execution_count": null, 609 | "metadata": { 610 | "execution": { 611 | "iopub.execute_input": "2024-07-31T20:21:28.269548Z", 612 | "iopub.status.busy": "2024-07-31T20:21:28.268891Z", 613 | "iopub.status.idle": "2024-07-31T20:22:01.045953Z", 614 | "shell.execute_reply": "2024-07-31T20:22:01.045026Z", 615 | "shell.execute_reply.started": "2024-07-31T20:21:28.269515Z" 616 | } 617 | }, 618 | "outputs": [], 619 | "source": [ 620 | "generate_answer(model, q1)" 621 | ] 622 | }, 623 | { 624 | "cell_type": "code", 625 | "execution_count": null, 626 | "metadata": {}, 627 | "outputs": [], 628 | "source": [ 629 | "generate_answer(model, q2)" 630 | ] 631 | }, 632 | { 633 | "cell_type": "code", 634 | "execution_count": null, 635 | "metadata": {}, 636 | "outputs": [], 637 | "source": [ 638 | "generate_answer(model, q3)" 639 | ] 640 | }, 641 | { 642 | "cell_type": "code", 643 | "execution_count": null, 644 | "metadata": {}, 645 | "outputs": [], 646 | "source": [ 647 | "# Free gpu memory\n", 648 | "import numba\n", 649 | "numba.cuda.close()" 650 | ] 651 | }, 652 | { 653 | "cell_type": "code", 654 | "execution_count": null, 655 | "metadata": {}, 656 | "outputs": [], 657 | "source": [] 658 | }, 659 | { 660 | "cell_type": "code", 661 | "execution_count": null, 662 | "metadata": { 663 | "execution": { 664 | "iopub.execute_input": "2024-07-31T20:29:40.007186Z", 665 | "iopub.status.busy": "2024-07-31T20:29:40.006418Z", 666 | "iopub.status.idle": "2024-07-31T20:30:00.561813Z", 667 | "shell.execute_reply": "2024-07-31T20:30:00.560849Z", 668 | "shell.execute_reply.started": "2024-07-31T20:29:40.00715Z" 669 | } 670 | }, 671 | "outputs": [], 672 | "source": [ 673 | "print(generate_answer(casual_model, q1))" 674 | ] 675 | }, 676 | { 677 | "cell_type": "code", 678 | "execution_count": null, 679 | "metadata": { 680 | "execution": { 681 | "iopub.status.busy": "2024-07-31T19:39:48.456683Z", 682 | "iopub.status.idle": "2024-07-31T19:39:48.457382Z", 683 | "shell.execute_reply": "2024-07-31T19:39:48.457144Z", 684 | "shell.execute_reply.started": "2024-07-31T19:39:48.457123Z" 685 | } 686 | }, 687 | "outputs": [], 688 | "source": [] 689 | }, 690 | { 691 | "cell_type": "code", 692 | "execution_count": null, 693 | "metadata": {}, 694 | "outputs": [], 695 | "source": [ 696 | "generate_answer(casual_model, q2)" 697 | ] 698 | }, 699 | { 700 | "cell_type": "code", 701 | "execution_count": null, 702 | "metadata": {}, 703 | "outputs": [], 704 | "source": [] 705 | }, 706 | { 707 | "cell_type": "code", 708 | "execution_count": null, 709 | "metadata": { 710 | "execution": { 711 | "iopub.status.busy": "2024-07-31T19:39:48.458644Z", 712 | "iopub.status.idle": "2024-07-31T19:39:48.459092Z", 713 | "shell.execute_reply": "2024-07-31T19:39:48.458882Z", 714 | "shell.execute_reply.started": "2024-07-31T19:39:48.458863Z" 715 | } 716 | }, 717 | "outputs": [], 718 | "source": [] 719 | }, 720 | { 721 | "cell_type": "code", 722 | "execution_count": null, 723 | "metadata": {}, 724 | "outputs": [], 725 | "source": [ 726 | "generate_answer(casual_model, q3)" 727 | ] 728 | }, 729 | { 730 | "cell_type": "code", 731 | "execution_count": null, 732 | "metadata": {}, 733 | "outputs": [], 734 | "source": [] 735 | } 736 | ], 737 | "metadata": { 738 | "kaggle": { 739 | "accelerator": "none", 740 | "dataSources": [], 741 | "dockerImageVersionId": 30747, 742 | "isGpuEnabled": false, 743 | "isInternetEnabled": true, 744 | "language": "python", 745 | "sourceType": "notebook" 746 | }, 747 | "kernelspec": { 748 | "display_name": "cv", 749 | "language": "python", 750 | "name": "python3" 751 | }, 752 | "language_info": { 753 | "codemirror_mode": { 754 | "name": "ipython", 755 | "version": 3 756 | }, 757 | "file_extension": ".py", 758 | "mimetype": "text/x-python", 759 | "name": "python", 760 | "nbconvert_exporter": "python", 761 | "pygments_lexer": "ipython3", 762 | "version": "3.10.12" 763 | } 764 | }, 765 | "nbformat": 4, 766 | "nbformat_minor": 4 767 | } 768 | -------------------------------------------------------------------------------- /notebooks/server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from fastapi import FastAPI 4 | from utils import ChatOpenAI, OpenAIEmbeddings 5 | from typing import Any 6 | 7 | from langserve import add_routes 8 | from langchain.pydantic_v1 import BaseModel 9 | from langchain.document_loaders import WebBaseLoader 10 | from langchain import hub 11 | from langchain.prompts import ChatPromptTemplate 12 | from langchain_community.vectorstores import FAISS 13 | from langchain_text_splitters import CharacterTextSplitter 14 | from langchain.tools.retriever import create_retriever_tool 15 | from langchain.agents import AgentExecutor, create_openai_tools_agent 16 | 17 | class Input(BaseModel): 18 | input: str 19 | 20 | 21 | class Output(BaseModel): 22 | output: Any 23 | 24 | def cut_output(output): 25 | return output['output'] 26 | 27 | 28 | loader = WebBaseLoader("https://allopizza.su/spb/kupchino/about") 29 | data = loader.load() 30 | 31 | course_api_key = ''# ключ курса (если используем ключи из курса) 32 | llm = ChatOpenAI(temperature=0.0, course_api_key=course_api_key) 33 | 34 | text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0) 35 | texts = text_splitter.split_documents(data) 36 | embeddings = OpenAIEmbeddings(course_api_key=course_api_key) 37 | db_embed = FAISS.from_documents(texts, embeddings) 38 | retriever = db_embed.as_retriever() 39 | 40 | tool = create_retriever_tool( 41 | retriever, # наш ретривер 42 | "search_web", # имя инструмента 43 | "Searches and returns data from page", # описание инструмента подается в ЛЛМ 44 | ) 45 | 46 | prompt = hub.pull("hwchase17/openai-tools-agent") 47 | 48 | agent = create_openai_tools_agent(llm, [tool], prompt) 49 | agent_executor = AgentExecutor(agent=agent, tools=[tool]) 50 | 51 | app = FastAPI( 52 | title="LangChain Server", 53 | version="1.0", 54 | description="A simple api server using Langchain's Runnable interfaces", 55 | ) 56 | 57 | add_routes( 58 | app, 59 | agent_executor.with_types(input_type=Input, output_type=Output) | cut_output, 60 | path="/rag_agent", # эндпоинт для rag агента 61 | ) 62 | 63 | prompt2 = ChatPromptTemplate.from_template("tell me a joke about {topic}") 64 | add_routes( 65 | app, 66 | prompt2 | llm, 67 | path="/joke", # эндпоинт для цепочки 68 | ) 69 | 70 | 71 | 72 | if __name__ == "__main__": 73 | import uvicorn 74 | 75 | uvicorn.run(app, host="0.0.0.0", port=8501) 76 | -------------------------------------------------------------------------------- /notebooks/utils.py: -------------------------------------------------------------------------------- 1 | import functools 2 | import inspect 3 | from typing import Callable, cast, Literal, List, Union, Optional, Dict 4 | import httpx 5 | import pydantic 6 | from openai import OpenAI, Stream, APIResponseValidationError, AsyncOpenAI 7 | from openai._base_client import make_request_options 8 | from openai._models import validate_type, construct_type, BaseModel 9 | #from pydantic import BaseModel 10 | from openai._resource import SyncAPIResource 11 | from openai._types import ResponseT, ModelBuilderProtocol, NotGiven, NOT_GIVEN, Headers, Query, Body 12 | from openai._utils import maybe_transform, required_args 13 | from openai.resources.chat import Completions as ChatCompletions 14 | from openai.resources import Completions 15 | from openai.types import CreateEmbeddingResponse, Completion, Embedding 16 | from openai.types.chat import ChatCompletion, ChatCompletionMessageParam, completion_create_params, \ 17 | ChatCompletionToolChoiceOptionParam, ChatCompletionToolParam, ChatCompletionChunk 18 | 19 | from langchain_openai import ChatOpenAI as GPT 20 | from langchain_openai import OpenAIEmbeddings as OpenAIEmbeds 21 | from langchain_core.utils import convert_to_secret_str 22 | 23 | 24 | class ChatGPTEntry(BaseModel): 25 | role: str 26 | content: str 27 | 28 | 29 | class ResponseSchema(BaseModel): 30 | response: ChatGPTEntry 31 | prompt_tokens: int 32 | completion_tokens: int 33 | available_tokens: int 34 | raw_openai_response: Union[ChatCompletion, Completion, None] = None 35 | 36 | 37 | def chat_completion_overload(func: Callable): 38 | @functools.wraps(func) 39 | def wrapper(*args, **kwargs): 40 | # trick to get openai schema from NDT custom schema 41 | # here is not ChatCompletion, here NDT schema but wrong casted ChatCompletion to inside openai lib 42 | #print(args, kwargs) 43 | result: ChatCompletion | Stream = func(*args, **kwargs) 44 | if isinstance(result, Stream): 45 | return result 46 | 47 | #print(result) 48 | ndt_response = ResponseSchema(**result.model_dump(exclude_unset=True, exclude_defaults=True)) 49 | #print(ndt_response.available_tokens) 50 | return ndt_response.raw_openai_response 51 | 52 | return wrapper 53 | 54 | 55 | class NDTChatCompletions(ChatCompletions): 56 | 57 | @required_args(["messages", "model"], ["messages", "model", "stream"]) 58 | def create( 59 | self, 60 | *, 61 | messages: List[ChatCompletionMessageParam], 62 | model: Union[ 63 | str, 64 | Literal[ 65 | "gpt-4-1106-preview", 66 | "gpt-4-vision-preview", 67 | "gpt-4", 68 | "gpt-4-0314", 69 | "gpt-4-0613", 70 | "gpt-4-32k", 71 | "gpt-4-32k-0314", 72 | "gpt-4-32k-0613", 73 | "gpt-3.5-turbo-1106", 74 | "gpt-3.5-turbo", 75 | "gpt-3.5-turbo-16k", 76 | "gpt-3.5-turbo-0301", 77 | "gpt-3.5-turbo-0613", 78 | "gpt-3.5-turbo-16k-0613", 79 | ], 80 | ], 81 | frequency_penalty: Optional[float] = NOT_GIVEN, 82 | function_call: completion_create_params.FunctionCall = NOT_GIVEN, 83 | functions: List[completion_create_params.Function] = NOT_GIVEN, 84 | logit_bias: Optional[Dict[str, int]] = NOT_GIVEN, 85 | max_tokens: Optional[int] = NOT_GIVEN, 86 | n: Optional[int] = NOT_GIVEN, 87 | presence_penalty: Optional[float] = NOT_GIVEN, 88 | response_format: completion_create_params.ResponseFormat = NOT_GIVEN, 89 | seed: Optional[int] = NOT_GIVEN, 90 | stop: Union[Optional[str], List[str]] = NOT_GIVEN, 91 | stream: Optional[Literal[False]] = NOT_GIVEN, 92 | temperature: Optional[float] = NOT_GIVEN, 93 | tool_choice: ChatCompletionToolChoiceOptionParam = NOT_GIVEN, 94 | tools: List[ChatCompletionToolParam] = NOT_GIVEN, 95 | top_p: Optional[float] = NOT_GIVEN, 96 | user: str = NOT_GIVEN, 97 | # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. 98 | # The extra values given here take precedence over values defined on the client or passed to this method. 99 | extra_headers: Headers = None, 100 | extra_query: Query = None, 101 | extra_body: Body = None, 102 | timeout: float = NOT_GIVEN, 103 | ) -> ChatCompletion: 104 | result: ResponseSchema = self._post( 105 | "/chat/completions", 106 | body=maybe_transform( 107 | { 108 | "messages": messages, 109 | "model": model, 110 | "frequency_penalty": frequency_penalty, 111 | "function_call": function_call, 112 | "functions": functions, 113 | "logit_bias": logit_bias, 114 | "max_tokens": max_tokens, 115 | "n": n, 116 | "presence_penalty": presence_penalty, 117 | "response_format": response_format, 118 | "seed": seed, 119 | "stop": stop, 120 | "stream": stream, 121 | "temperature": temperature, 122 | "tool_choice": tool_choice, 123 | "tools": tools, 124 | "top_p": top_p, 125 | "user": user, 126 | }, 127 | completion_create_params.CompletionCreateParams, 128 | ), 129 | options=make_request_options( 130 | extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout 131 | ), 132 | cast_to=ResponseSchema, 133 | stream=stream or False, 134 | stream_cls=Stream[ChatCompletionChunk], 135 | ) 136 | 137 | #print(result) 138 | return result.raw_openai_response 139 | 140 | 141 | class NDTCompletions(Completions): 142 | 143 | @required_args(["model", "prompt"], ["model", "prompt", "stream"]) 144 | def create( 145 | self, 146 | *, 147 | model: Union[ 148 | str, 149 | Literal[ 150 | "babbage-002", 151 | "davinci-002", 152 | "gpt-3.5-turbo-instruct", 153 | "text-davinci-003", 154 | "text-davinci-002", 155 | "text-davinci-001", 156 | "code-davinci-002", 157 | "text-curie-001", 158 | "text-babbage-001", 159 | "text-ada-001", 160 | ], 161 | ], 162 | prompt: Union[str, List[str], List[int], List[List[int]], None], 163 | best_of: Optional[int] = NOT_GIVEN, 164 | echo: Optional[bool] = NOT_GIVEN, 165 | frequency_penalty: Optional[float] = NOT_GIVEN, 166 | logit_bias: Optional[Dict[str, int]] = NOT_GIVEN, 167 | logprobs: Optional[int] = NOT_GIVEN, 168 | max_tokens: Optional[int] = NOT_GIVEN, 169 | n: Optional[int] = NOT_GIVEN, 170 | presence_penalty: Optional[float] = NOT_GIVEN, 171 | seed: Optional[int] = NOT_GIVEN, 172 | stop: Union[Optional[str], List[str], None] = NOT_GIVEN, 173 | stream: Optional[Literal[False]] = NOT_GIVEN, 174 | suffix: Optional[str] = NOT_GIVEN, 175 | temperature: Optional[float] = NOT_GIVEN, 176 | top_p: Optional[float] = NOT_GIVEN, 177 | user: str = NOT_GIVEN, 178 | # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. 179 | # The extra values given here take precedence over values defined on the client or passed to this method. 180 | extra_headers: Headers = None, 181 | extra_query: Query = None, 182 | extra_body: Body = None, 183 | timeout: float = NOT_GIVEN, 184 | ) -> Completion: 185 | result: ResponseSchema = self._post( 186 | "/completions", 187 | body=maybe_transform( 188 | { 189 | "model": model, 190 | "prompt": prompt, 191 | "best_of": best_of, 192 | "echo": echo, 193 | "frequency_penalty": frequency_penalty, 194 | "logit_bias": logit_bias, 195 | "logprobs": logprobs, 196 | "max_tokens": max_tokens, 197 | "n": n, 198 | "presence_penalty": presence_penalty, 199 | "seed": seed, 200 | "stop": stop, 201 | "stream": stream, 202 | "suffix": suffix, 203 | "temperature": temperature, 204 | "top_p": top_p, 205 | "user": user, 206 | }, 207 | completion_create_params.CompletionCreateParams, 208 | ), 209 | options=make_request_options( 210 | extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout 211 | ), 212 | cast_to=ResponseSchema, 213 | stream=stream or False, 214 | stream_cls=Stream[Completion], 215 | ) 216 | 217 | #print(result) 218 | import time 219 | time.sleep(5) 220 | return result.raw_openai_response 221 | 222 | 223 | 224 | class NDTChat(SyncAPIResource): 225 | completions: NDTChatCompletions 226 | 227 | def __init__(self, client: OpenAI) -> None: 228 | super().__init__(client) 229 | self.completions = NDTChatCompletions(client) 230 | 231 | 232 | class EmbeddingResponseSchema(BaseModel): 233 | data: list[Embedding] 234 | prompt_tokens: int 235 | available_tokens: int 236 | raw_openai_response: CreateEmbeddingResponse = None 237 | 238 | 239 | def embeddings_overload(func: Callable): 240 | @functools.wraps(func) 241 | def wrapper(*args, **kwargs): 242 | # trick to get openai schema from NDT custom schema 243 | # here is not CreateEmbeddingResponse, here NDT schema but wrong casted CreateEmbeddingResponse to inside openai lib 244 | result: CreateEmbeddingResponse = func(*args, **kwargs) 245 | ndt_response = EmbeddingResponseSchema(**result.model_dump(exclude_unset=True, exclude_defaults=True)) 246 | #print(ndt_response.available_tokens) 247 | return ndt_response.raw_openai_response 248 | 249 | return wrapper 250 | 251 | 252 | class NDTOpenAI(OpenAI): 253 | # chat: NDTChat 254 | # completions: NDTCompletions 255 | server_url: str = "https://api.neuraldeep.tech/" 256 | 257 | def __init__(self, api_key, **kwargs): 258 | super().__init__(api_key=api_key, base_url=self.server_url, **kwargs) 259 | # self.embeddings.create = embeddings_overload(self.embeddings.create) 260 | # self.chat = NDTChat(self) 261 | # self.completions = NDTCompletions(self) 262 | 263 | class AsyncNDTOpenAI(AsyncOpenAI): 264 | server_url: str = "https://api.neuraldeep.tech/" 265 | def __init__(self, api_key, **kwargs): 266 | super().__init__(api_key=api_key, base_url=self.server_url, **kwargs) 267 | 268 | 269 | class ChatOpenAI(GPT): 270 | 271 | ''' 272 | Класс ChatOpenAI по аналогии с одноименным классом из библиотеки langchain 273 | ''' 274 | 275 | openai_api_key: str = convert_to_secret_str('api_key') 276 | 277 | def __init__(self, course_api_key, **kwargs): 278 | super().__init__(client = NDTOpenAI(api_key=course_api_key).chat.completions, async_client= AsyncNDTOpenAI(api_key=course_api_key).chat.completions, **kwargs) 279 | 280 | 281 | class OpenAIEmbeddings(OpenAIEmbeds): 282 | 283 | ''' 284 | Класс OpenAIEmbeddings по аналогии с одноименным классом из библиотеки langchain 285 | ''' 286 | 287 | openai_api_key: str = convert_to_secret_str('api_key') 288 | 289 | 290 | def __init__(self, course_api_key, **kwargs): 291 | super().__init__(client = NDTOpenAI(api_key=course_api_key).embeddings, async_client= AsyncNDTOpenAI(api_key=course_api_key).embeddings, **kwargs) 292 | -------------------------------------------------------------------------------- /streamlit-project/README.md: -------------------------------------------------------------------------------- 1 | # LangChain Ask the Doc app 2 | Доступно по ссылке: https://langchain-test-f6ijcdouysewpy7ad9dqlo.streamlit.app/ -------------------------------------------------------------------------------- /streamlit-project/app.py: -------------------------------------------------------------------------------- 1 | import streamlit as st 2 | from langchain.llms import OpenAI 3 | from langchain.text_splitter import CharacterTextSplitter 4 | from langchain.embeddings import OpenAIEmbeddings 5 | from langchain.vectorstores import Chroma 6 | from langchain.chains import RetrievalQA 7 | 8 | def generate_response(uploaded_file, openai_api_key, query_text): 9 | # Load document if file is uploaded 10 | if uploaded_file is not None: 11 | documents = [uploaded_file.read().decode()] 12 | # Split documents into chunks 13 | text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0) 14 | texts = text_splitter.create_documents(documents) 15 | # Select embeddings 16 | embeddings = OpenAIEmbeddings(openai_api_key=openai_api_key) 17 | # Create a vectorstore from documents 18 | db = Chroma.from_documents(texts, embeddings) 19 | # Create retriever interface 20 | retriever = db.as_retriever() 21 | # Create QA chain 22 | qa = RetrievalQA.from_chain_type(llm=OpenAI(openai_api_key=openai_api_key), chain_type='stuff', retriever=retriever) 23 | return qa.run(query_text) 24 | 25 | # Page title 26 | st.set_page_config(page_title='🦜🔗 Ask the Doc App') 27 | st.title('🦜🔗 Ask the Doc App') 28 | 29 | # File upload 30 | uploaded_file = st.file_uploader('Upload an article', type='txt') 31 | # Query text 32 | query_text = st.text_input('Enter your question:', placeholder = 'Please provide a short summary.', disabled=not uploaded_file) 33 | 34 | # Form input and query 35 | result = [] 36 | with st.form('myform', clear_on_submit=True): 37 | openai_api_key = st.text_input('OpenAI API Key', type='password', disabled=not (uploaded_file and query_text)) 38 | submitted = st.form_submit_button('Submit', disabled=not(uploaded_file and query_text)) 39 | if submitted and openai_api_key.startswith('sk-'): 40 | with st.spinner('Calculating...'): 41 | response = generate_response(uploaded_file, openai_api_key, query_text) 42 | result.append(response) 43 | del openai_api_key 44 | 45 | if len(result): 46 | st.info(response) -------------------------------------------------------------------------------- /streamlit-project/app_v2.py: -------------------------------------------------------------------------------- 1 | import streamlit as st 2 | from audiorecorder import audiorecorder 3 | 4 | st.title("Streamlit + LLM") 5 | st.caption("🚀 Dodo AI") 6 | 7 | with st.sidebar: 8 | openai_api_key = st.text_input("OpenAI API Key", key="chatbot_api_key", type="password") 9 | "[Get an OpenAI API key](https://platform.openai.com/account/api-keys)" 10 | 11 | def generate_response(input_text): 12 | st.info(input_text) 13 | # llm = OpenAI(temperature=0.7, openai_api_key=openai_api_key) 14 | # st.info(llm(input_text)) 15 | 16 | with st.form('my_form'): 17 | text = st.text_area('Enter text:', 'What are the three key pieces of advice for learning how to code?') 18 | submitted = st.form_submit_button('Submit') 19 | if not openai_api_key.startswith('sk-'): 20 | st.warning('Please enter your OpenAI API key!', icon='⚠') 21 | if submitted and openai_api_key.startswith('sk-'): 22 | generate_response(text) 23 | 24 | audio = audiorecorder("", "") 25 | 26 | if len(audio) > 0: 27 | # To play audio in frontend: 28 | st.audio(audio.export().read()) 29 | 30 | # To save audio to a file, use pydub export method: 31 | audio.export("audio.wav", format="wav") 32 | 33 | # To get audio properties, use pydub AudioSegment properties: 34 | st.write(f"Frame rate: {audio.frame_rate}, Frame width: {audio.frame_width}, Duration: {audio.duration_seconds} seconds") 35 | -------------------------------------------------------------------------------- /streamlit-project/dockerfile: -------------------------------------------------------------------------------- 1 | # Используем базовый образ Python 2 | FROM python:3.11-slim 3 | 4 | # Устанавливаем рабочую директорию внутри контейнера 5 | WORKDIR /app 6 | 7 | # Копируем зависимости проекта в контейнер 8 | COPY requirements.txt . 9 | 10 | # Устанавливаем зависимости проекта 11 | RUN pip install --upgrade pip && \ 12 | pip install --no-cache-dir -r requirements.txt 13 | 14 | # Копируем все файлы проекта в контейнер 15 | COPY . . 16 | 17 | # Открываем порт, на котором будет работать приложение Streamlit 18 | EXPOSE 8501 19 | 20 | # Запускаем приложение Streamlit 21 | CMD ["streamlit", "run", "app.py"] -------------------------------------------------------------------------------- /streamlit-project/requirements.txt: -------------------------------------------------------------------------------- 1 | aiohttp==3.8.5 2 | aiosignal==1.3.1 3 | altair==5.1.1 4 | annotated-types==0.5.0 5 | anyio==4.0.0 6 | async-timeout==4.0.3 7 | attrs==23.1.0 8 | backoff==2.2.1 9 | bcrypt==4.0.1 10 | blinker==1.6.2 11 | cachetools==5.3.1 12 | certifi==2023.7.22 13 | charset-normalizer==3.2.0 14 | chroma-hnswlib==0.7.3 15 | chromadb==0.4.10 16 | click==8.1.7 17 | coloredlogs==15.0.1 18 | dataclasses-json==0.5.14 19 | fastapi==0.99.1 20 | filelock==3.12.4 21 | flatbuffers==23.5.26 22 | frozenlist==1.4.0 23 | fsspec==2023.9.1 24 | gitdb==4.0.10 25 | GitPython==3.1.36 26 | greenlet==2.0.2 27 | h11==0.14.0 28 | httptools==0.6.0 29 | huggingface-hub==0.16.4 30 | humanfriendly==10.0 31 | idna==3.4 32 | importlib-metadata==6.8.0 33 | importlib-resources==6.0.1 34 | Jinja2==3.1.2 35 | jsonschema==4.19.0 36 | jsonschema-specifications==2023.7.1 37 | langchain==0.0.292 38 | langsmith==0.0.38 39 | markdown-it-py==3.0.0 40 | MarkupSafe==2.1.3 41 | marshmallow==3.20.1 42 | mdurl==0.1.2 43 | monotonic==1.6 44 | mpmath==1.3.0 45 | multidict==6.0.4 46 | mypy-extensions==1.0.0 47 | numexpr==2.8.6 48 | numpy==1.26.0 49 | onnxruntime==1.15.1 50 | openai==0.28.0 51 | overrides==7.4.0 52 | packaging==23.1 53 | pandas==2.1.0 54 | Pillow==9.5.0 55 | posthog==3.0.2 56 | protobuf==4.24.3 57 | pulsar-client==3.3.0 58 | pyarrow==13.0.0 59 | pydantic==1.10.12 60 | pydantic_core==2.6.3 61 | pydeck==0.8.0 62 | Pygments==2.16.1 63 | Pympler==1.0.1 64 | PyPika==0.48.9 65 | python-dateutil==2.8.2 66 | python-dotenv==1.0.0 67 | pytz==2023.3.post1 68 | pytz-deprecation-shim==0.1.0.post0 69 | PyYAML==6.0.1 70 | referencing==0.30.2 71 | regex==2023.8.8 72 | requests==2.31.0 73 | rich==13.5.3 74 | rpds-py==0.10.3 75 | six==1.16.0 76 | smmap==5.0.1 77 | sniffio==1.3.0 78 | SQLAlchemy==2.0.20 79 | starlette==0.27.0 80 | streamlit==1.26.0 81 | sympy==1.12 82 | tenacity==8.2.3 83 | tiktoken==0.5.1 84 | tokenizers==0.14.0 85 | toml==0.10.2 86 | toolz==0.12.0 87 | tornado==6.3.3 88 | tqdm==4.66.1 89 | typing-inspect==0.9.0 90 | typing_extensions==4.8.0 91 | tzdata==2023.3 92 | tzlocal==4.3.1 93 | urllib3==2.0.4 94 | uvicorn==0.23.2 95 | uvloop==0.17.0 96 | validators==0.22.0 97 | watchfiles==0.20.0 98 | websockets==11.0.3 99 | yarl==1.9.2 100 | zipp==3.16.2 101 | -------------------------------------------------------------------------------- /whisper_bot_project/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/f2bc5a92c8fa7056f783d2dfbc2114616292cd26/whisper_bot_project/README.md --------------------------------------------------------------------------------