├── .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, ?B/s]"
714 | ]
715 | },
716 | "metadata": {},
717 | "output_type": "display_data"
718 | },
719 | {
720 | "data": {
721 | "application/vnd.jupyter.widget-view+json": {
722 | "model_id": "d93ebd4bf19940d482d2f54e494ca0cc",
723 | "version_major": 2,
724 | "version_minor": 0
725 | },
726 | "text/plain": [
727 | "Downloading (…)olve/main/merges.txt: 0%| | 0.00/456k [00:00, ?B/s]"
728 | ]
729 | },
730 | "metadata": {},
731 | "output_type": "display_data"
732 | },
733 | {
734 | "data": {
735 | "application/vnd.jupyter.widget-view+json": {
736 | "model_id": "b139563b147b4dd3949064916122729d",
737 | "version_major": 2,
738 | "version_minor": 0
739 | },
740 | "text/plain": [
741 | "Downloading (…)/main/tokenizer.json: 0%| | 0.00/1.36M [00:00, ?B/s]"
742 | ]
743 | },
744 | "metadata": {},
745 | "output_type": "display_data"
746 | },
747 | {
748 | "data": {
749 | "application/vnd.jupyter.widget-view+json": {
750 | "model_id": "2f30c202fe3a4b7e9d9c79a79c7d2bc7",
751 | "version_major": 2,
752 | "version_minor": 0
753 | },
754 | "text/plain": [
755 | "Downloading (…)lve/main/config.json: 0%| | 0.00/665 [00:00, ?B/s]"
756 | ]
757 | },
758 | "metadata": {},
759 | "output_type": "display_data"
760 | },
761 | {
762 | "data": {
763 | "text/plain": [
764 | "{'history': 'AI: Как дела?\\nHuman: Спасибо, хорошо!\\nAI: Здорово!'}"
765 | ]
766 | },
767 | "execution_count": 14,
768 | "metadata": {},
769 | "output_type": "execute_result"
770 | }
771 | ],
772 | "source": [
773 | "from langchain.memory import ConversationTokenBufferMemory\n",
774 | "\n",
775 | "# Инициализируем новый token-буфер, подаем в него модель и лимит токенов\n",
776 | "# Модель подаём потому что модели по-разному токенизируют текст\n",
777 | "memory = ConversationTokenBufferMemory(llm=llm, max_token_limit=50)\n",
778 | "\n",
779 | "memory.save_context({\"input\": \"Привет!\"}, \n",
780 | " {\"output\": \"Как дела?\"})\n",
781 | "memory.save_context({\"input\": \"Спасибо, хорошо!\"}, \n",
782 | " {\"output\": \"Здорово!\"})\n",
783 | "\n",
784 | "memory.load_memory_variables({}) # видим, что по лимиту прошли только последние 3 фразы"
785 | ]
786 | },
787 | {
788 | "cell_type": "markdown",
789 | "id": "0ff31547-6ab1-4c21-9ce6-64ea2b98c746",
790 | "metadata": {},
791 | "source": [
792 | "##
🗜🗣 `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 | " text | \n",
178 | "
\n",
179 | " \n",
180 | " \n",
181 | " \n",
182 | " 0 | \n",
183 | " | \n",
184 | "
\n",
185 | " \n",
186 | " 1 | \n",
187 | " | \n",
188 | "
\n",
189 | " \n",
190 | " 2 | \n",
191 | " Всем привет!\\n\\nРешил запустить свой канал. Бу... | \n",
192 | "
\n",
193 | " \n",
194 | " 3 | \n",
195 | " Когда начинаешь погружаться в DS - начинаешь р... | \n",
196 | "
\n",
197 | " \n",
198 | " 4 | \n",
199 | " #лайфхаки\\nПоймал себя на периодическом подгля... | \n",
200 | "
\n",
201 | " \n",
202 | "
\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 | " Instruction | \n",
263 | " Input | \n",
264 | " Response | \n",
265 | "
\n",
266 | " \n",
267 | " \n",
268 | " \n",
269 | " 0 | \n",
270 | " Write a post on the following topic | \n",
271 | " | \n",
272 | " Всем привет!\\n\\nРешил запустить свой канал. Бу... | \n",
273 | "
\n",
274 | " \n",
275 | " 1 | \n",
276 | " Write a post on the following topic | \n",
277 | " | \n",
278 | " Когда начинаешь погружаться в DS - начинаешь р... | \n",
279 | "
\n",
280 | " \n",
281 | " 2 | \n",
282 | " Write a post on the following topic | \n",
283 | " | \n",
284 | " #лайфхаки\\nПоймал себя на периодическом подгля... | \n",
285 | "
\n",
286 | " \n",
287 | " 3 | \n",
288 | " Write a post on the following topic | \n",
289 | " | \n",
290 | " Speed up'ал, speed up'аю и буду speed up'ать с... | \n",
291 | "
\n",
292 | " \n",
293 | " 4 | \n",
294 | " Write a post on the following topic | \n",
295 | " | \n",
296 | " За этот месяц раз 5 услышал слово \"экстраполяц... | \n",
297 | "
\n",
298 | " \n",
299 | "
\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 | " Instruction | \n",
450 | " Input | \n",
451 | " Response | \n",
452 | "
\n",
453 | " \n",
454 | " \n",
455 | " \n",
456 | " 0 | \n",
457 | " Write a post on the following topic | \n",
458 | " Запуск канала о Data Science | \n",
459 | " Всем привет!\\n\\nРешил запустить свой канал. Бу... | \n",
460 | "
\n",
461 | " \n",
462 | " 1 | \n",
463 | " Write a post on the following topic | \n",
464 | " Простые примеры кода для новых методов/алгоритмов | \n",
465 | " Когда начинаешь погружаться в DS - начинаешь р... | \n",
466 | "
\n",
467 | " \n",
468 | " 2 | \n",
469 | " Write a post on the following topic | \n",
470 | " Полезные расширения для работы с табличными да... | \n",
471 | " #лайфхаки\\nПоймал себя на периодическом подгля... | \n",
472 | "
\n",
473 | " \n",
474 | " 3 | \n",
475 | " Write a post on the following topic | \n",
476 | " Ways to speed up Pytorch training on Kaggle | \n",
477 | " Speed up'ал, speed up'аю и буду speed up'ать с... | \n",
478 | "
\n",
479 | " \n",
480 | " 4 | \n",
481 | " Write a post on the following topic | \n",
482 | " Интерпретация моделей в машинном обучении | \n",
483 | " За этот месяц раз 5 услышал слово \"экстраполяц... | \n",
484 | "
\n",
485 | " \n",
486 | "
\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, ?B/s]"
576 | ]
577 | },
578 | "metadata": {},
579 | "output_type": "display_data"
580 | },
581 | {
582 | "data": {
583 | "application/vnd.jupyter.widget-view+json": {
584 | "model_id": "5d754fe6aab047f6b85026cd0d27ec6c",
585 | "version_major": 2,
586 | "version_minor": 0
587 | },
588 | "text/plain": [
589 | "Downloading data: 0%| | 0.00/662k [00:00, ?B/s]"
590 | ]
591 | },
592 | "metadata": {},
593 | "output_type": "display_data"
594 | },
595 | {
596 | "data": {
597 | "application/vnd.jupyter.widget-view+json": {
598 | "model_id": "3cf694ee03f140cc94889e099db74697",
599 | "version_major": 2,
600 | "version_minor": 0
601 | },
602 | "text/plain": [
603 | "Generating train split: 0%| | 0/587 [00:00, ? examples/s]"
604 | ]
605 | },
606 | "metadata": {},
607 | "output_type": "display_data"
608 | }
609 | ],
610 | "source": [
611 | "# Попробуем его подгрузить прямо с HuggingFace\n",
612 | "from datasets import load_dataset\n",
613 | "\n",
614 | "dataset = load_dataset(\"Ivanich/datafeeling_posts\")"
615 | ]
616 | },
617 | {
618 | "cell_type": "code",
619 | "execution_count": 24,
620 | "id": "1327f2a0-785b-47ba-81a5-80de41fa6549",
621 | "metadata": {},
622 | "outputs": [
623 | {
624 | "data": {
625 | "text/plain": [
626 | "DatasetDict({\n",
627 | " train: Dataset({\n",
628 | " features: ['Instruction', 'Input', 'Response'],\n",
629 | " num_rows: 587\n",
630 | " })\n",
631 | "})"
632 | ]
633 | },
634 | "execution_count": 24,
635 | "metadata": {},
636 | "output_type": "execute_result"
637 | }
638 | ],
639 | "source": [
640 | "dataset"
641 | ]
642 | },
643 | {
644 | "cell_type": "code",
645 | "execution_count": 26,
646 | "id": "56b29e2c-5f70-444c-963d-5b1b93dfda86",
647 | "metadata": {},
648 | "outputs": [
649 | {
650 | "data": {
651 | "text/plain": [
652 | "{'Instruction': 'Write a post on the following topic',\n",
653 | " 'Input': 'Запуск канала о Data Science',\n",
654 | " 'Response': 'Всем привет!\\n\\nРешил запустить свой канал. Буду рассказывать здесь про свой опыт в Data Science и лайфхаки'}"
655 | ]
656 | },
657 | "execution_count": 26,
658 | "metadata": {},
659 | "output_type": "execute_result"
660 | }
661 | ],
662 | "source": [
663 | "dataset['train'][0]"
664 | ]
665 | },
666 | {
667 | "cell_type": "markdown",
668 | "id": "be699ae3-8e44-4540-9d98-c35503dad107",
669 | "metadata": {},
670 | "source": [
671 | "### В следующем ноутбуке c помощью этого датасета будем файнтюнить Llama 3.1"
672 | ]
673 | }
674 | ],
675 | "metadata": {
676 | "kernelspec": {
677 | "display_name": "cv",
678 | "language": "python",
679 | "name": "python3"
680 | },
681 | "language_info": {
682 | "codemirror_mode": {
683 | "name": "ipython",
684 | "version": 3
685 | },
686 | "file_extension": ".py",
687 | "mimetype": "text/x-python",
688 | "name": "python",
689 | "nbconvert_exporter": "python",
690 | "pygments_lexer": "ipython3",
691 | "version": "3.10.12"
692 | }
693 | },
694 | "nbformat": 4,
695 | "nbformat_minor": 5
696 | }
697 |
--------------------------------------------------------------------------------
/notebooks/M5_fine_tuning_llama-3-1_peft.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "_cell_guid": "b1076dfc-b9ad-4769-8c92-a6c4dae69d19",
7 | "_uuid": "8f2839f25d086af736a60e9eeb907d3b93b6e0e5"
8 | },
9 | "source": [
10 | "# Libraries"
11 | ]
12 | },
13 | {
14 | "cell_type": "code",
15 | "execution_count": null,
16 | "metadata": {
17 | "execution": {
18 | "iopub.execute_input": "2024-07-31T19:19:36.421057Z",
19 | "iopub.status.busy": "2024-07-31T19:19:36.420121Z",
20 | "iopub.status.idle": "2024-07-31T19:20:22.145747Z",
21 | "shell.execute_reply": "2024-07-31T19:20:22.144324Z",
22 | "shell.execute_reply.started": "2024-07-31T19:19:36.421009Z"
23 | }
24 | },
25 | "outputs": [],
26 | "source": [
27 | "%%capture\n",
28 | "\n",
29 | "%pip install -U peft\n",
30 | "%pip install -U trl\n",
31 | "%pip install -U bitsandbytes "
32 | ]
33 | },
34 | {
35 | "cell_type": "code",
36 | "execution_count": null,
37 | "metadata": {
38 | "execution": {
39 | "iopub.execute_input": "2024-07-31T19:20:22.148355Z",
40 | "iopub.status.busy": "2024-07-31T19:20:22.148024Z",
41 | "iopub.status.idle": "2024-07-31T19:20:44.164336Z",
42 | "shell.execute_reply": "2024-07-31T19:20:44.163538Z",
43 | "shell.execute_reply.started": "2024-07-31T19:20:22.148324Z"
44 | }
45 | },
46 | "outputs": [],
47 | "source": [
48 | "import os, torch, wandb\n",
49 | "\n",
50 | "from transformers import (\n",
51 | " AutoModelForCausalLM,\n",
52 | " AutoTokenizer,\n",
53 | " BitsAndBytesConfig,\n",
54 | " HfArgumentParser,\n",
55 | " TrainingArguments,\n",
56 | " pipeline,\n",
57 | " logging,\n",
58 | ")\n",
59 | "from peft import (\n",
60 | " LoraConfig,\n",
61 | " PeftModel,\n",
62 | " prepare_model_for_kbit_training,\n",
63 | " get_peft_model,\n",
64 | ")\n",
65 | "\n",
66 | "from datasets import load_dataset\n",
67 | "from trl import SFTTrainer, setup_chat_format\n",
68 | "from dataclasses import dataclass"
69 | ]
70 | },
71 | {
72 | "cell_type": "markdown",
73 | "metadata": {},
74 | "source": [
75 | "## Setup Huggingface 🤗 & Wandb"
76 | ]
77 | },
78 | {
79 | "cell_type": "code",
80 | "execution_count": null,
81 | "metadata": {
82 | "execution": {
83 | "iopub.execute_input": "2024-07-31T19:20:44.16689Z",
84 | "iopub.status.busy": "2024-07-31T19:20:44.165909Z",
85 | "iopub.status.idle": "2024-07-31T19:20:46.965276Z",
86 | "shell.execute_reply": "2024-07-31T19:20:46.964266Z",
87 | "shell.execute_reply.started": "2024-07-31T19:20:44.166853Z"
88 | }
89 | },
90 | "outputs": [],
91 | "source": [
92 | "from huggingface_hub import login\n",
93 | "from kaggle_secrets import UserSecretsClient\n",
94 | "user_secrets = UserSecretsClient()\n",
95 | "\n",
96 | "hf_token = user_secrets.get_secret(\"huggingface_token\")\n",
97 | "\n",
98 | "login(token = hf_token)\n",
99 | "\n",
100 | "wb_token = user_secrets.get_secret(\"wandb_api_key\")\n",
101 | "\n",
102 | "wandb.login(key=wb_token)"
103 | ]
104 | },
105 | {
106 | "cell_type": "code",
107 | "execution_count": null,
108 | "metadata": {
109 | "execution": {
110 | "iopub.execute_input": "2024-07-31T19:20:46.969022Z",
111 | "iopub.status.busy": "2024-07-31T19:20:46.967876Z",
112 | "iopub.status.idle": "2024-07-31T19:20:46.974308Z",
113 | "shell.execute_reply": "2024-07-31T19:20:46.973252Z",
114 | "shell.execute_reply.started": "2024-07-31T19:20:46.968992Z"
115 | }
116 | },
117 | "outputs": [],
118 | "source": [
119 | "@dataclass\n",
120 | "class Config:\n",
121 | "# model_name = \"meta-llama/Meta-Llama-3.1-8B-Instruct\"\n",
122 | "# model_name = \"AnatoliiPotapov/T-lite-instruct-0.1\"\n",
123 | " model_name = \"google/gemma-2-9b-it\"\n",
124 | " dataset_name = \"ruslanmv/ai-medical-chatbot\"\n",
125 | " new_model = \"llama-3.1-8b-chat-doctor\"\n",
126 | " torch_dtype = torch.float16\n",
127 | " attn_implementation = \"eager\"\n",
128 | "cfg = Config()"
129 | ]
130 | },
131 | {
132 | "cell_type": "markdown",
133 | "metadata": {},
134 | "source": [
135 | "# Loading model and tokenizer"
136 | ]
137 | },
138 | {
139 | "cell_type": "code",
140 | "execution_count": null,
141 | "metadata": {
142 | "execution": {
143 | "iopub.execute_input": "2024-07-31T19:20:46.975766Z",
144 | "iopub.status.busy": "2024-07-31T19:20:46.975431Z",
145 | "iopub.status.idle": "2024-07-31T19:23:16.014332Z",
146 | "shell.execute_reply": "2024-07-31T19:23:16.013378Z",
147 | "shell.execute_reply.started": "2024-07-31T19:20:46.975741Z"
148 | }
149 | },
150 | "outputs": [],
151 | "source": [
152 | "# QLoRA config\n",
153 | "bnb_config = BitsAndBytesConfig(\n",
154 | " load_in_4bit=True,\n",
155 | " bnb_4bit_quant_type=\"nf4\",\n",
156 | " bnb_4bit_compute_dtype=cfg.torch_dtype,\n",
157 | " bnb_4bit_use_double_quant=True,\n",
158 | ")\n",
159 | "\n",
160 | "# Load model\n",
161 | "model = AutoModelForCausalLM.from_pretrained(\n",
162 | " cfg.model_name,\n",
163 | " quantization_config=bnb_config,\n",
164 | " device_map=\"auto\",\n",
165 | " attn_implementation=cfg.attn_implementation\n",
166 | ")"
167 | ]
168 | },
169 | {
170 | "cell_type": "code",
171 | "execution_count": null,
172 | "metadata": {
173 | "execution": {
174 | "iopub.execute_input": "2024-07-31T19:23:16.015907Z",
175 | "iopub.status.busy": "2024-07-31T19:23:16.015614Z",
176 | "iopub.status.idle": "2024-07-31T19:23:18.405382Z",
177 | "shell.execute_reply": "2024-07-31T19:23:18.404549Z",
178 | "shell.execute_reply.started": "2024-07-31T19:23:16.015883Z"
179 | }
180 | },
181 | "outputs": [],
182 | "source": [
183 | "# Load tokenizer\n",
184 | "tokenizer = AutoTokenizer.from_pretrained(cfg.model_name)\n",
185 | "model, tokenizer = setup_chat_format(model, tokenizer)\n",
186 | "tokenizer.padding_side = 'right'\n",
187 | "tokenizer.padding_token = '<|pad|>'"
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
--------------------------------------------------------------------------------