"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Data Scientist.: Dr.Eddy Giusepe Chirinos Isidro"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Outros links des estudo para Fine-Tuning:\n",
"\n",
"* [Fine Tuning OpenAI’s GPT3 model](https://medium.com/@_sumitsaha_/fine-tuning-openais-gpt3-model-fd9cb06517f6)\n",
"\n",
"* [datacamp: Fine-Tuning GPT-3 Using the OpenAI API and Python](https://www.datacamp.com/tutorial/fine-tuning-gpt-3-using-the-open-ai-api-and-python)\n",
"\n",
"\n",
"Também: nomes personalizados do `fine-tuning`:\n",
"\n",
"$ openai api fine_tunes.create -t test.jsonl -m ada --suffix \"custom model name\" ----> criará: `ada:ft-your-org:custom-model-name-2022-02-15-04-21-04`\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Neste Notebook vamos realizar o `Fine-Tuning` de um Classificador `ADA` para distinguir entre os dois esportes: `Baseball` e `Hockey`."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Importação e exploração de Dados"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"O conjunto de dados do `newsgroup` pode ser carregado usando sklearn. "
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.datasets import fetch_20newsgroups\n",
"import pandas as pd\n",
"import openai\n",
"\n",
"\n",
"categories = ['rec.sport.baseball', 'rec.sport.hockey']\n",
"sports_dataset = fetch_20newsgroups(subset='train', shuffle=True, random_state=42, categories=categories)\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
".. _20newsgroups_dataset:\n",
"\n",
"The 20 newsgroups text dataset\n",
"------------------------------\n",
"\n",
"The 20 newsgroups dataset comprises around 18000 newsgroups posts on\n",
"20 topics split in two subsets: one for training (or development)\n",
"and the other one for testing (or for performance evaluation). The split\n",
"between the train and test set is based upon a messages posted before\n",
"and after a specific date.\n",
"\n",
"This module contains two loaders. The first one,\n",
":func:`sklearn.datasets.fetch_20newsgroups`,\n",
"returns a list of the raw texts that can be fed to text feature\n",
"extractors such as :class:`~sklearn.feature_extraction.text.CountVectorizer`\n",
"with custom parameters so as to extract feature vectors.\n",
"The second one, :func:`sklearn.datasets.fetch_20newsgroups_vectorized`,\n",
"returns ready-to-use features, i.e., it is not necessary to use a feature\n",
"extractor.\n",
"\n",
"**Data Set Characteristics:**\n",
"\n",
" ================= ==========\n",
" Classes 20\n",
" Samples total 18846\n",
" Dimensionality 1\n",
" Features text\n",
" ================= ==========\n",
"\n",
"|details-start|\n",
"**Usage**\n",
"|details-split|\n",
"\n",
"The :func:`sklearn.datasets.fetch_20newsgroups` function is a data\n",
"fetching / caching functions that downloads the data archive from\n",
"the original `20 newsgroups website`_, extracts the archive contents\n",
"in the ``~/scikit_learn_data/20news_home`` folder and calls the\n",
":func:`sklearn.datasets.load_files` on either the training or\n",
"testing set folder, or both of them::\n",
"\n",
" >>> from sklearn.datasets import fetch_20newsgroups\n",
" >>> newsgroups_train = fetch_20newsgroups(subset='train')\n",
"\n",
" >>> from pprint import pprint\n",
" >>> pprint(list(newsgroups_train.target_names))\n",
" ['alt.atheism',\n",
" 'comp.graphics',\n",
" 'comp.os.ms-windows.misc',\n",
" 'comp.sys.ibm.pc.hardware',\n",
" 'comp.sys.mac.hardware',\n",
" 'comp.windows.x',\n",
" 'misc.forsale',\n",
" 'rec.autos',\n",
" 'rec.motorcycles',\n",
" 'rec.sport.baseball',\n",
" 'rec.sport.hockey',\n",
" 'sci.crypt',\n",
" 'sci.electronics',\n",
" 'sci.med',\n",
" 'sci.space',\n",
" 'soc.religion.christian',\n",
" 'talk.politics.guns',\n",
" 'talk.politics.mideast',\n",
" 'talk.politics.misc',\n",
" 'talk.religion.misc']\n",
"\n",
"The real data lies in the ``filenames`` and ``target`` attributes. The target\n",
"attribute is the integer index of the category::\n",
"\n",
" >>> newsgroups_train.filenames.shape\n",
" (11314,)\n",
" >>> newsgroups_train.target.shape\n",
" (11314,)\n",
" >>> newsgroups_train.target[:10]\n",
" array([ 7, 4, 4, 1, 14, 16, 13, 3, 2, 4])\n",
"\n",
"It is possible to load only a sub-selection of the categories by passing the\n",
"list of the categories to load to the\n",
":func:`sklearn.datasets.fetch_20newsgroups` function::\n",
"\n",
" >>> cats = ['alt.atheism', 'sci.space']\n",
" >>> newsgroups_train = fetch_20newsgroups(subset='train', categories=cats)\n",
"\n",
" >>> list(newsgroups_train.target_names)\n",
" ['alt.atheism', 'sci.space']\n",
" >>> newsgroups_train.filenames.shape\n",
" (1073,)\n",
" >>> newsgroups_train.target.shape\n",
" (1073,)\n",
" >>> newsgroups_train.target[:10]\n",
" array([0, 1, 1, 1, 0, 1, 1, 0, 0, 0])\n",
"\n",
"|details-end|\n",
"\n",
"|details-start|\n",
"**Converting text to vectors**\n",
"|details-split|\n",
"\n",
"In order to feed predictive or clustering models with the text data,\n",
"one first need to turn the text into vectors of numerical values suitable\n",
"for statistical analysis. This can be achieved with the utilities of the\n",
"``sklearn.feature_extraction.text`` as demonstrated in the following\n",
"example that extract `TF-IDF`_ vectors of unigram tokens\n",
"from a subset of 20news::\n",
"\n",
" >>> from sklearn.feature_extraction.text import TfidfVectorizer\n",
" >>> categories = ['alt.atheism', 'talk.religion.misc',\n",
" ... 'comp.graphics', 'sci.space']\n",
" >>> newsgroups_train = fetch_20newsgroups(subset='train',\n",
" ... categories=categories)\n",
" >>> vectorizer = TfidfVectorizer()\n",
" >>> vectors = vectorizer.fit_transform(newsgroups_train.data)\n",
" >>> vectors.shape\n",
" (2034, 34118)\n",
"\n",
"The extracted TF-IDF vectors are very sparse, with an average of 159 non-zero\n",
"components by sample in a more than 30000-dimensional space\n",
"(less than .5% non-zero features)::\n",
"\n",
" >>> vectors.nnz / float(vectors.shape[0])\n",
" 159.01327...\n",
"\n",
":func:`sklearn.datasets.fetch_20newsgroups_vectorized` is a function which\n",
"returns ready-to-use token counts features instead of file names.\n",
"\n",
".. _`20 newsgroups website`: http://people.csail.mit.edu/jrennie/20Newsgroups/\n",
".. _`TF-IDF`: https://en.wikipedia.org/wiki/Tf-idf\n",
"\n",
"|details-end|\n",
"\n",
"|details-start|\n",
"**Filtering text for more realistic training**\n",
"|details-split|\n",
"\n",
"It is easy for a classifier to overfit on particular things that appear in the\n",
"20 Newsgroups data, such as newsgroup headers. Many classifiers achieve very\n",
"high F-scores, but their results would not generalize to other documents that\n",
"aren't from this window of time.\n",
"\n",
"For example, let's look at the results of a multinomial Naive Bayes classifier,\n",
"which is fast to train and achieves a decent F-score::\n",
"\n",
" >>> from sklearn.naive_bayes import MultinomialNB\n",
" >>> from sklearn import metrics\n",
" >>> newsgroups_test = fetch_20newsgroups(subset='test',\n",
" ... categories=categories)\n",
" >>> vectors_test = vectorizer.transform(newsgroups_test.data)\n",
" >>> clf = MultinomialNB(alpha=.01)\n",
" >>> clf.fit(vectors, newsgroups_train.target)\n",
" MultinomialNB(alpha=0.01, class_prior=None, fit_prior=True)\n",
"\n",
" >>> pred = clf.predict(vectors_test)\n",
" >>> metrics.f1_score(newsgroups_test.target, pred, average='macro')\n",
" 0.88213...\n",
"\n",
"(The example :ref:`sphx_glr_auto_examples_text_plot_document_classification_20newsgroups.py` shuffles\n",
"the training and test data, instead of segmenting by time, and in that case\n",
"multinomial Naive Bayes gets a much higher F-score of 0.88. Are you suspicious\n",
"yet of what's going on inside this classifier?)\n",
"\n",
"Let's take a look at what the most informative features are:\n",
"\n",
" >>> import numpy as np\n",
" >>> def show_top10(classifier, vectorizer, categories):\n",
" ... feature_names = vectorizer.get_feature_names_out()\n",
" ... for i, category in enumerate(categories):\n",
" ... top10 = np.argsort(classifier.coef_[i])[-10:]\n",
" ... print(\"%s: %s\" % (category, \" \".join(feature_names[top10])))\n",
" ...\n",
" >>> show_top10(clf, vectorizer, newsgroups_train.target_names)\n",
" alt.atheism: edu it and in you that is of to the\n",
" comp.graphics: edu in graphics it is for and of to the\n",
" sci.space: edu it that is in and space to of the\n",
" talk.religion.misc: not it you in is that and to of the\n",
"\n",
"\n",
"You can now see many things that these features have overfit to:\n",
"\n",
"- Almost every group is distinguished by whether headers such as\n",
" ``NNTP-Posting-Host:`` and ``Distribution:`` appear more or less often.\n",
"- Another significant feature involves whether the sender is affiliated with\n",
" a university, as indicated either by their headers or their signature.\n",
"- The word \"article\" is a significant feature, based on how often people quote\n",
" previous posts like this: \"In article [article ID], [name] <[e-mail address]>\n",
" wrote:\"\n",
"- Other features match the names and e-mail addresses of particular people who\n",
" were posting at the time.\n",
"\n",
"With such an abundance of clues that distinguish newsgroups, the classifiers\n",
"barely have to identify topics from text at all, and they all perform at the\n",
"same high level.\n",
"\n",
"For this reason, the functions that load 20 Newsgroups data provide a\n",
"parameter called **remove**, telling it what kinds of information to strip out\n",
"of each file. **remove** should be a tuple containing any subset of\n",
"``('headers', 'footers', 'quotes')``, telling it to remove headers, signature\n",
"blocks, and quotation blocks respectively.\n",
"\n",
" >>> newsgroups_test = fetch_20newsgroups(subset='test',\n",
" ... remove=('headers', 'footers', 'quotes'),\n",
" ... categories=categories)\n",
" >>> vectors_test = vectorizer.transform(newsgroups_test.data)\n",
" >>> pred = clf.predict(vectors_test)\n",
" >>> metrics.f1_score(pred, newsgroups_test.target, average='macro')\n",
" 0.77310...\n",
"\n",
"This classifier lost over a lot of its F-score, just because we removed\n",
"metadata that has little to do with topic classification.\n",
"It loses even more if we also strip this metadata from the training data:\n",
"\n",
" >>> newsgroups_train = fetch_20newsgroups(subset='train',\n",
" ... remove=('headers', 'footers', 'quotes'),\n",
" ... categories=categories)\n",
" >>> vectors = vectorizer.fit_transform(newsgroups_train.data)\n",
" >>> clf = MultinomialNB(alpha=.01)\n",
" >>> clf.fit(vectors, newsgroups_train.target)\n",
" MultinomialNB(alpha=0.01, class_prior=None, fit_prior=True)\n",
"\n",
" >>> vectors_test = vectorizer.transform(newsgroups_test.data)\n",
" >>> pred = clf.predict(vectors_test)\n",
" >>> metrics.f1_score(newsgroups_test.target, pred, average='macro')\n",
" 0.76995...\n",
"\n",
"Some other classifiers cope better with this harder version of the task. Try the\n",
":ref:`sphx_glr_auto_examples_model_selection_plot_grid_search_text_feature_extraction.py`\n",
"example with and without the `remove` option to compare the results.\n",
"|details-end|\n",
"\n",
".. topic:: Data Considerations\n",
"\n",
" The Cleveland Indians is a major league baseball team based in Cleveland,\n",
" Ohio, USA. In December 2020, it was reported that \"After several months of\n",
" discussion sparked by the death of George Floyd and a national reckoning over\n",
" race and colonialism, the Cleveland Indians have decided to change their\n",
" name.\" Team owner Paul Dolan \"did make it clear that the team will not make\n",
" its informal nickname -- the Tribe -- its new team name.\" \"It's not going to\n",
" be a half-step away from the Indians,\" Dolan said.\"We will not have a Native\n",
" American-themed name.\"\n",
"\n",
" https://www.mlb.com/news/cleveland-indians-team-name-change\n",
"\n",
".. topic:: Recommendation\n",
"\n",
" - When evaluating text classifiers on the 20 Newsgroups data, you\n",
" should strip newsgroup-related metadata. In scikit-learn, you can do this\n",
" by setting ``remove=('headers', 'footers', 'quotes')``. The F-score will be\n",
" lower because it is more realistic.\n",
" - This text dataset contains data which may be inappropriate for certain NLP\n",
" applications. An example is listed in the \"Data Considerations\" section\n",
" above. The challenge with using current text datasets in NLP for tasks such\n",
" as sentence completion, clustering, and other applications is that text\n",
" that is culturally biased and inflammatory will propagate biases. This\n",
" should be taken into consideration when using the dataset, reviewing the\n",
" output, and the bias should be documented.\n",
"\n",
".. topic:: Examples\n",
"\n",
" * :ref:`sphx_glr_auto_examples_model_selection_plot_grid_search_text_feature_extraction.py`\n",
"\n",
" * :ref:`sphx_glr_auto_examples_text_plot_document_classification_20newsgroups.py`\n",
"\n",
" * :ref:`sphx_glr_auto_examples_text_plot_hashing_vs_dict_vectorizer.py`\n",
"\n",
" * :ref:`sphx_glr_auto_examples_text_plot_document_clustering.py`\n",
"\n"
]
}
],
"source": [
"print(sports_dataset['DESCR'])"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['rec.sport.baseball', 'rec.sport.hockey']\n"
]
}
],
"source": [
"print(sports_dataset['target_names'])"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"From: dougb@comm.mot.com (Doug Bank)\n",
"Subject: Re: Info needed for Cleveland tickets\n",
"Reply-To: dougb@ecs.comm.mot.com\n",
"Organization: Motorola Land Mobile Products Sector\n",
"Distribution: usa\n",
"Nntp-Posting-Host: 145.1.146.35\n",
"Lines: 17\n",
"\n",
"In article <1993Apr1.234031.4950@leland.Stanford.EDU>, bohnert@leland.Stanford.EDU (matthew bohnert) writes:\n",
"\n",
"|> I'm going to be in Cleveland Thursday, April 15 to Sunday, April 18.\n",
"|> Does anybody know if the Tribe will be in town on those dates, and\n",
"|> if so, who're they playing and if tickets are available?\n",
"\n",
"The tribe will be in town from April 16 to the 19th.\n",
"There are ALWAYS tickets available! (Though they are playing Toronto,\n",
"and many Toronto fans make the trip to Cleveland as it is easier to\n",
"get tickets in Cleveland than in Toronto. Either way, I seriously\n",
"doubt they will sell out until the end of the season.)\n",
"\n",
"-- \n",
"Doug Bank Private Systems Division\n",
"dougb@ecs.comm.mot.com Motorola Communications Sector\n",
"dougb@nwu.edu Schaumburg, Illinois\n",
"dougb@casbah.acns.nwu.edu 708-576-8207 \n",
"\n"
]
}
],
"source": [
"print(sports_dataset['data'][0])"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'rec.sport.baseball'"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sports_dataset.target_names[sports_dataset['target'][0]]"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Total examples: 1197, Baseball examples: 597, Hockey examples: 600\n"
]
}
],
"source": [
"len_all, len_baseball, len_hockey = len(sports_dataset.data), len([e for e in sports_dataset.target if e == 0]), len([e for e in sports_dataset.target if e == 1])\n",
"\n",
"\n",
"print(f\"Total examples: {len_all}, Baseball examples: {len_baseball}, Hockey examples: {len_hockey}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Preparação de dados"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Transformamos o conjunto de dados em um dataframe do `pandas`, com uma coluna para `prompt` e `completion`. O `prompt` contém o `e-mail` da lista de discussão e a `completion` é o nome do esporte, seja `hockey` ou `baseball`. Apenas para fins de demonstração e velocidade de ``Fine-Tuning, tomamos apenas `300` exemplos. `Em um caso de uso real, quanto mais exemplos melhor será o desempenho.`"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
Subject: Let it be Known\\nFrom: <ISSBTL@BYUVM....
\n",
"
baseball
\n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" prompt completion\n",
"0 From: dougb@comm.mot.com (Doug Bank)\\nSubject:... baseball\n",
"1 From: gld@cunixb.cc.columbia.edu (Gary L Dare)... hockey\n",
"2 From: rudy@netcom.com (Rudy Wade)\\nSubject: Re... baseball\n",
"3 From: monack@helium.gas.uug.arizona.edu (david... hockey\n",
"4 Subject: Let it be Known\\nFrom: Tanto o `baseball` quanto o `hockey` são tokens únicos. Salvamos o conjunto de dados como um arquivo `jsonl`."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"# orient='records' --> Significa que cada linha do DataFrame será convertida em um registro JSON separado no arquivo. Cada registro JSON conterá os dados de uma linha do DataFrame.\n",
"# lines=True --> Este argumento indica que os registros JSON devem ser escritos em linhas separadas no arquivo JSONL.\n",
"df.to_json(\"sport2.jsonl\", orient='records', lines=True)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Tool de preparação de dados"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Agora podemos usar uma `tool de preparação de dados` que irá sugerir algumas melhorias em nosso conjunto de dados antes do `Fine-Tuning`. Antes de lançar a Tool, atualizamos a biblioteca `openai` para garantir que estamos usando a Tool de preparação de dados mais recente. Além disso, especificamos `-q` que aceita automaticamente todas as sugestões."
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Requirement already satisfied: openai in ./venv_Classification/lib/python3.10/site-packages (0.28.1)\n",
"Requirement already satisfied: aiohttp in ./venv_Classification/lib/python3.10/site-packages (from openai) (3.8.5)\n",
"Requirement already satisfied: tqdm in ./venv_Classification/lib/python3.10/site-packages (from openai) (4.66.1)\n",
"Requirement already satisfied: requests>=2.20 in ./venv_Classification/lib/python3.10/site-packages (from openai) (2.31.0)\n",
"Requirement already satisfied: certifi>=2017.4.17 in ./venv_Classification/lib/python3.10/site-packages (from requests>=2.20->openai) (2023.7.22)\n",
"Requirement already satisfied: charset-normalizer<4,>=2 in ./venv_Classification/lib/python3.10/site-packages (from requests>=2.20->openai) (3.3.0)\n",
"Requirement already satisfied: idna<4,>=2.5 in ./venv_Classification/lib/python3.10/site-packages (from requests>=2.20->openai) (3.4)\n",
"Requirement already satisfied: urllib3<3,>=1.21.1 in ./venv_Classification/lib/python3.10/site-packages (from requests>=2.20->openai) (2.0.6)\n",
"Requirement already satisfied: attrs>=17.3.0 in ./venv_Classification/lib/python3.10/site-packages (from aiohttp->openai) (23.1.0)\n",
"Requirement already satisfied: async-timeout<5.0,>=4.0.0a3 in ./venv_Classification/lib/python3.10/site-packages (from aiohttp->openai) (4.0.3)\n",
"Requirement already satisfied: aiosignal>=1.1.2 in ./venv_Classification/lib/python3.10/site-packages (from aiohttp->openai) (1.3.1)\n",
"Requirement already satisfied: frozenlist>=1.1.1 in ./venv_Classification/lib/python3.10/site-packages (from aiohttp->openai) (1.4.0)\n",
"Requirement already satisfied: yarl<2.0,>=1.0 in ./venv_Classification/lib/python3.10/site-packages (from aiohttp->openai) (1.9.2)\n",
"Requirement already satisfied: multidict<7.0,>=4.5 in ./venv_Classification/lib/python3.10/site-packages (from aiohttp->openai) (6.0.4)\n",
"Note: you may need to restart the kernel to use updated packages.\n"
]
}
],
"source": [
"%pip install --upgrade openai"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Analyzing...\n",
"\n",
"- Your file contains 1197 prompt-completion pairs\n",
"- Based on your data it seems like you're trying to fine-tune a model for classification\n",
"- For classification, we recommend you try one of the faster and cheaper models, such as `ada`\n",
"- For classification, you can estimate the expected model performance by keeping a held out dataset, which is not used for training\n",
"- There are 11 examples that are very long. These are rows: [134, 200, 281, 320, 404, 595, 704, 838, 1113, 1139, 1174]\n",
"For conditional generation, and for classification the examples shouldn't be longer than 2048 tokens.\n",
"- Your data does not contain a common separator at the end of your prompts. Having a separator string appended to the end of the prompt makes it clearer to the fine-tuned model where the completion should begin. See https://platform.openai.com/docs/guides/fine-tuning/preparing-your-dataset for more detail and examples. If you intend to do open-ended generation, then you should leave the prompts empty\n",
"- The completion should start with a whitespace character (` `). This tends to produce better results due to the tokenization we use. See https://platform.openai.com/docs/guides/fine-tuning/preparing-your-dataset for more details\n",
"\n",
"Based on the analysis we will perform the following actions:\n",
"- [Recommended] Remove 11 long examples [Y/n]: Y\n",
"- [Recommended] Add a suffix separator `\\n\\n###\\n\\n` to all prompts [Y/n]: Y\n",
"- [Recommended] Add a whitespace character to the beginning of the completion [Y/n]: Y\n",
"- [Recommended] Would you like to split into training and validation set? [Y/n]: Y\n",
"\n",
"\n",
"Your data will be written to a new JSONL file. Proceed [Y/n]: Y\n",
"\n",
"Wrote modified files to `sport2_prepared_train.jsonl` and `sport2_prepared_valid.jsonl`\n",
"Feel free to take a look!\n",
"\n",
"Now use that file when fine-tuning:\n",
"> openai api fine_tunes.create -t \"sport2_prepared_train.jsonl\" -v \"sport2_prepared_valid.jsonl\" --compute_classification_metrics --classification_positive_class \" baseball\"\n",
"\n",
"After you’ve fine-tuned a model, remember that your prompt has to end with the indicator string `\\n\\n###\\n\\n` for the model to start generating completions, rather than continuing with the prompt.\n",
"Once your model starts training, it'll approximately take 30.8 minutes to train a `curie` model, and less for `ada` and `babbage`. Queue will approximately take half an hour per job ahead of you.\n"
]
}
],
"source": [
"# Ver também: openai tools fine_tunes.prepare_data -f qa.txt\n",
"\n",
"!openai tools fine_tunes.prepare_data -f sport2.jsonl -q"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A ferramenta sugere algumas melhorias no conjunto de dados e divide o conjunto de dados em conjunto de `Treinamento` e `Validação`.\n",
"\n",
"Um `suffix` entre um `prompt` e o `completion` é necessário para informar ao modelo que o texto de entrada foi interrompido e que agora ele precisa prever a `classe`. Como usamos o mesmo separador em cada exemplo, o modelo é capaz de aprender que se destina a prever o `baseball` or `hockey` seguindo o separador. Um `prefix` de espaço em branco nas `completions` é útil, pois a maioria dos tokens de palavras são tokenizados com um `prefix` de espaço. A ferramenta (`Tool`) também reconheceu que esta é provavelmente uma tarefa de `classificação`, por isso sugeriu dividir o conjunto de dados em conjuntos de dados de Treinamento e Validação. Isso nos permitirá medir facilmente o desempenho esperado em novos dados."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Fine-Tuning"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A ferramenta sugere que executemos o seguinte comando para treinar o conjunto de dados. Como esta é uma `task de classificação`, gostaríamos de saber qual é o desempenho de `generalização` no conjunto de `validação` fornecido para nosso caso de uso de classificação. A ferramenta sugere adicionar `--compute_classification_metrics --classification_positive_class \"baseball\"` para calcular as métricas de classificação.\n",
"\n",
"Podemos simplesmente copiar o comando sugerido da ferramenta CLI. Adicionamos especificamente `-m ada` para o `Fine-Tuning` do modelo `ada` mais barato e mais rápido, que geralmente é comparável em desempenho a modelos mais lentos e mais caros em casos de uso de classificação."
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Training File ID: file-iGfQPTiV6hwy5fV2J7Y4YQpW\n"
]
}
],
"source": [
"# Data_train:\n",
"Data_train = openai.File.create(file=open(\"/home/eddygiusepe/1_Eddy_Giusepe/6_REPO_HuggingFace/15_Binary_classification_fine-tuning/sport2_prepared_train.jsonl\", \"rb\"),\n",
" purpose='fine-tune'\n",
" )\n",
"\n",
"training_file_id = Data_train[\"id\"]\n",
"print(f\"Training File ID: {training_file_id}\")\n"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Validation File ID: file-9Ur6ctNs3Pfyfywql1lp7PO4\n"
]
}
],
"source": [
"# Data_valid:\n",
"Data_train = openai.File.create(file=open(\"/home/eddygiusepe/1_Eddy_Giusepe/6_REPO_HuggingFace/15_Binary_classification_fine-tuning/sport2_prepared_valid.jsonl\", \"rb\"),\n",
" purpose='fine-tune'\n",
" )\n",
"\n",
"validation_file_id = Data_train[\"id\"]\n",
"print(f\"Validation File ID: {validation_file_id}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Excluir os arquivos:\n",
"\n",
"openai.File.delete(\"file-WyKeDhoOpOz6DryMemOimyvW\")\n",
"\n",
"openai.File.delete(\"file-mzyk3q314rgKyQxQnr5oBx0j\")"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [],
"source": [
"#DEPRECATED ---> !openai api fine_tunes.create -t \"sport2_prepared_train.jsonl\" -v \"sport2_prepared_valid.jsonl\" --compute_classification_metrics --classification_positive_class \" baseball\" -m ada\n",
"\n",
"# Descomentar para treinar: (CUIDADO NÃO EXECUTAR VARIAS VEZES NÃO❗❗❗)\n",
"\n",
"Fine_Tuning =openai.FineTuningJob.create(\n",
" \t\t\t\t\t\t\t\t\ttraining_file=training_file_id,\n",
" \t\t\tvalidation_file=validation_file_id,\n",
" \t\t\tmodel=\"davinci-002\",\n",
" \t\t\thyperparameters={\"n_epochs\":4},\n",
" suffix=\"Eddy_BinaryClass\")\n"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
" JSON: {\n",
" \"object\": \"fine_tuning.job\",\n",
" \"id\": \"ftjob-ytgarjLNymFEcrKYtDUup2yL\",\n",
" \"model\": \"davinci-002\",\n",
" \"created_at\": 1696536241,\n",
" \"finished_at\": null,\n",
" \"fine_tuned_model\": null,\n",
" \"organization_id\": \"org-cSA8PDGrKC1wEWr130vOKCM0\",\n",
" \"result_files\": [],\n",
" \"status\": \"validating_files\",\n",
" \"validation_file\": \"file-9Ur6ctNs3Pfyfywql1lp7PO4\",\n",
" \"training_file\": \"file-iGfQPTiV6hwy5fV2J7Y4YQpW\",\n",
" \"hyperparameters\": {\n",
" \"n_epochs\": 4\n",
" },\n",
" \"trained_tokens\": null,\n",
" \"error\": null\n",
"}"
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Fine_Tuning"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'ftjob-ytgarjLNymFEcrKYtDUup2yL'"
]
},
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Fine_Tuning_id = Fine_Tuning[\"id\"]\n",
"Fine_Tuning_id"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Para cancelar o Treinamento:\n",
"\n",
"openai.FineTuningJob.cancel(\"ftjob-MYm8Gj37kEI3ynM6tHimWTGA\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"O modelo é treinado com sucesso em cerca de dez minutos. Podemos ver que o nome do modelo é `ada:ft-openai-2021-07-30-12-26-20`, que podemos usar para fazer inferências."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Resultados e desempenho esperado do Modelo"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Agora podemos fazer `download` do arquivo de resultados para observar o desempenho esperado em um conjunto de `validação` retido."
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
" JSON: {\n",
" \"object\": \"fine_tuning.job\",\n",
" \"id\": \"ftjob-ytgarjLNymFEcrKYtDUup2yL\",\n",
" \"model\": \"davinci-002\",\n",
" \"created_at\": 1696536241,\n",
" \"finished_at\": 1696536406,\n",
" \"fine_tuned_model\": \"ft:davinci-002:personal:eddy-binaryclass:86OuN8we\",\n",
" \"organization_id\": \"org-cSA8PDGrKC1wEWr130vOKCM0\",\n",
" \"result_files\": [\n",
" \"file-3ZqS55VbHhldKCTQNzIUQoFK\"\n",
" ],\n",
" \"status\": \"succeeded\",\n",
" \"validation_file\": \"file-9Ur6ctNs3Pfyfywql1lp7PO4\",\n",
" \"training_file\": \"file-iGfQPTiV6hwy5fV2J7Y4YQpW\",\n",
" \"hyperparameters\": {\n",
" \"n_epochs\": 4\n",
" },\n",
" \"trained_tokens\": 41764,\n",
" \"error\": null\n",
"}"
]
},
"execution_count": 47,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Usamos o seguinte comando ---> https://platform.openai.com/docs/api-reference/fine-tuning/retrieve\n",
"\n",
"openai.FineTuningJob.retrieve(\"ftjob-ytgarjLNymFEcrKYtDUup2yL\")"
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
" JSON: {\n",
" \"object\": \"file\",\n",
" \"id\": \"file-3ZqS55VbHhldKCTQNzIUQoFK\",\n",
" \"purpose\": \"fine-tune-results\",\n",
" \"filename\": \"step_metrics.csv\",\n",
" \"bytes\": 1811,\n",
" \"created_at\": 1696536409,\n",
" \"status\": \"processed\",\n",
" \"status_details\": null\n",
"}"
]
},
"execution_count": 53,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"xxx= openai.File.retrieve(\"file-3ZqS55VbHhldKCTQNzIUQoFK\")\n",
"\n",
"xxx"
]
},
{
"cell_type": "code",
"execution_count": 62,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"b'step,train_loss,train_accuracy,valid_loss,valid_mean_token_accuracy\\n1,15.81906,0.0,14.67002,0.0\\n2,13.07276,0.0,15.50881,0.0\\n3,13.87567,0.0,16.25,0.0\\n4,13.3373,0.0,12.77298,0.0\\n5,14.30848,0.0,12.6235,0.0\\n6,13.32132,0.0,11.60394,0.0\\n7,12.9074,0.0,11.67611,0.0\\n8,12.5918,0.0,9.70959,0.0\\n9,11.56537,0.0,8.65894,0.0\\n10,8.10063,0.0,15.49833,0.0\\n11,4.67463,0.0,4.4466,0.0\\n12,5.78812,0.0,3.59255,0.0\\n13,4.91947,0.0,1.81759,0.0\\n14,1.67461,0.0,1.37271,1.0\\n15,0.45382,1.0,0.02368,1.0\\n16,0.89798,1.0,0.05735,1.0\\n17,0.03383,1.0,0.03698,1.0\\n18,0.20682,1.0,0.00484,1.0\\n19,0.03163,1.0,0.00079,1.0\\n20,0.00083,1.0,0.00017,1.0\\n21,0.00013,1.0,4e-05,1.0\\n22,1e-05,1.0,1e-05,1.0\\n23,1e-05,1.0,0.0,1.0\\n24,0.0,1.0,0.0,1.0\\n25,0.0,1.0,2e-05,1.0\\n26,0.0,1.0,0.0,1.0\\n27,0.0,1.0,0.0,1.0\\n28,0.0,1.0,0.0,1.0\\n29,0.0,1.0,-0.0,1.0\\n30,0.0,1.0,0.99869,0.0\\n31,0.0,1.0,0.0,1.0\\n32,0.0,1.0,-0.0,1.0\\n33,0.0,1.0,-0.0,1.0\\n34,0.0,1.0,-0.0,1.0\\n35,0.0,1.0,-0.0,1.0\\n36,0.0,1.0,-0.0,1.0\\n37,0.0,1.0,-0.0,1.0\\n38,0.0,1.0,-0.0,1.0\\n39,0.0,1.0,-0.0,1.0\\n40,0.0,1.0,-0.0,1.0\\n41,0.0,1.0,-0.0,1.0\\n42,0.0,1.0,-0.0,1.0\\n43,0.0,1.0,-0.0,1.0\\n44,0.0,1.0,-0.0,1.0\\n45,0.0,1.0,0.0,1.0\\n46,0.0,1.0,-0.0,1.0\\n47,0.0,1.0,-0.0,1.0\\n48,1e-05,1.0,-0.0,1.0\\n49,0.0,1.0,0.0,1.0\\n50,0.0,1.0,9.84829,0.0\\n51,0.0,1.0,-0.0,1.0\\n52,0.0,1.0,-0.0,1.0\\n53,0.0,1.0,0.0,1.0\\n54,0.0,1.0,0.0,1.0\\n55,0.0,1.0,-0.0,1.0\\n56,0.0,1.0,0.0,1.0\\n57,0.0,1.0,-0.0,1.0\\n58,0.0,1.0,-0.0,1.0\\n59,0.0,1.0,-0.0,1.0\\n60,0.0,1.0,-0.0,1.0\\n61,0.0,1.0,0.0,1.0\\n62,0.0,1.0,-0.0,1.0\\n63,0.0,1.0,0.0,1.0\\n64,0.0,1.0,-0.0,1.0\\n65,0.0,1.0,-0.0,1.0\\n66,0.0,1.0,-0.0,1.0\\n67,0.0,1.0,-0.0,1.0\\n68,0.0,1.0,-0.0,1.0\\n69,0.0,1.0,0.0,1.0\\n70,0.0,1.0,9.45719,0.0\\n71,0.0,1.0,-0.0,1.0\\n72,0.0,1.0,-0.0,1.0\\n73,0.0,1.0,0.0,1.0\\n74,0.0,1.0,3e-05,1.0\\n75,0.0,1.0,0.0,1.0\\n76,0.0,1.0,0.0,1.0\\n77,0.0,1.0,0.0,1.0\\n78,0.0,1.0,0.0,1.0\\n79,0.0,1.0,-0.0,1.0\\n80,0.0,1.0,0.0,1.0\\n'"
]
},
"execution_count": 62,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# !openai api fine_tunes.results -i ft-vAbAQIPmy69zOyssgt5zI3VE > result.csv\n",
"\n",
"# Aqui usamos para recuperar nosso RESULTADOS ---> https://platform.openai.com/docs/api-reference/files/retrieve-contents\n",
"content = openai.File.download(\"file-3ZqS55VbHhldKCTQNzIUQoFK\")\n",
"\n",
"content"
]
},
{
"cell_type": "code",
"execution_count": 63,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'step,train_loss,train_accuracy,valid_loss,valid_mean_token_accuracy\\n1,15.81906,0.0,14.67002,0.0\\n2,13.07276,0.0,15.50881,0.0\\n3,13.87567,0.0,16.25,0.0\\n4,13.3373,0.0,12.77298,0.0\\n5,14.30848,0.0,12.6235,0.0\\n6,13.32132,0.0,11.60394,0.0\\n7,12.9074,0.0,11.67611,0.0\\n8,12.5918,0.0,9.70959,0.0\\n9,11.56537,0.0,8.65894,0.0\\n10,8.10063,0.0,15.49833,0.0\\n11,4.67463,0.0,4.4466,0.0\\n12,5.78812,0.0,3.59255,0.0\\n13,4.91947,0.0,1.81759,0.0\\n14,1.67461,0.0,1.37271,1.0\\n15,0.45382,1.0,0.02368,1.0\\n16,0.89798,1.0,0.05735,1.0\\n17,0.03383,1.0,0.03698,1.0\\n18,0.20682,1.0,0.00484,1.0\\n19,0.03163,1.0,0.00079,1.0\\n20,0.00083,1.0,0.00017,1.0\\n21,0.00013,1.0,4e-05,1.0\\n22,1e-05,1.0,1e-05,1.0\\n23,1e-05,1.0,0.0,1.0\\n24,0.0,1.0,0.0,1.0\\n25,0.0,1.0,2e-05,1.0\\n26,0.0,1.0,0.0,1.0\\n27,0.0,1.0,0.0,1.0\\n28,0.0,1.0,0.0,1.0\\n29,0.0,1.0,-0.0,1.0\\n30,0.0,1.0,0.99869,0.0\\n31,0.0,1.0,0.0,1.0\\n32,0.0,1.0,-0.0,1.0\\n33,0.0,1.0,-0.0,1.0\\n34,0.0,1.0,-0.0,1.0\\n35,0.0,1.0,-0.0,1.0\\n36,0.0,1.0,-0.0,1.0\\n37,0.0,1.0,-0.0,1.0\\n38,0.0,1.0,-0.0,1.0\\n39,0.0,1.0,-0.0,1.0\\n40,0.0,1.0,-0.0,1.0\\n41,0.0,1.0,-0.0,1.0\\n42,0.0,1.0,-0.0,1.0\\n43,0.0,1.0,-0.0,1.0\\n44,0.0,1.0,-0.0,1.0\\n45,0.0,1.0,0.0,1.0\\n46,0.0,1.0,-0.0,1.0\\n47,0.0,1.0,-0.0,1.0\\n48,1e-05,1.0,-0.0,1.0\\n49,0.0,1.0,0.0,1.0\\n50,0.0,1.0,9.84829,0.0\\n51,0.0,1.0,-0.0,1.0\\n52,0.0,1.0,-0.0,1.0\\n53,0.0,1.0,0.0,1.0\\n54,0.0,1.0,0.0,1.0\\n55,0.0,1.0,-0.0,1.0\\n56,0.0,1.0,0.0,1.0\\n57,0.0,1.0,-0.0,1.0\\n58,0.0,1.0,-0.0,1.0\\n59,0.0,1.0,-0.0,1.0\\n60,0.0,1.0,-0.0,1.0\\n61,0.0,1.0,0.0,1.0\\n62,0.0,1.0,-0.0,1.0\\n63,0.0,1.0,0.0,1.0\\n64,0.0,1.0,-0.0,1.0\\n65,0.0,1.0,-0.0,1.0\\n66,0.0,1.0,-0.0,1.0\\n67,0.0,1.0,-0.0,1.0\\n68,0.0,1.0,-0.0,1.0\\n69,0.0,1.0,0.0,1.0\\n70,0.0,1.0,9.45719,0.0\\n71,0.0,1.0,-0.0,1.0\\n72,0.0,1.0,-0.0,1.0\\n73,0.0,1.0,0.0,1.0\\n74,0.0,1.0,3e-05,1.0\\n75,0.0,1.0,0.0,1.0\\n76,0.0,1.0,0.0,1.0\\n77,0.0,1.0,0.0,1.0\\n78,0.0,1.0,0.0,1.0\\n79,0.0,1.0,-0.0,1.0\\n80,0.0,1.0,0.0,1.0\\n'"
]
},
"execution_count": 63,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"CSV_content = content.decode(\"utf-8\")\n",
"CSV_content"
]
},
{
"cell_type": "code",
"execution_count": 64,
"metadata": {},
"outputs": [],
"source": [
"with open(\"CSV_content_RESULT.csv\", \"w\", newline='') as file:\n",
" file.write(CSV_content)"
]
},
{
"cell_type": "code",
"execution_count": 69,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
"
],
"text/plain": [
" prompt completion\n",
"0 From: gld@cunixb.cc.columbia.edu (Gary L Dare)... hockey\n",
"1 From: smorris@venus.lerc.nasa.gov (Ron Morris ... hockey\n",
"2 From: golchowy@alchemy.chem.utoronto.ca (Geral... hockey\n",
"3 From: krattige@hpcc01.corp.hp.com (Kim Krattig... baseball\n",
"4 From: warped@cs.montana.edu (Doug Dolven)\\nSub... baseball"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"test = pd.read_json('sport2_prepared_valid.jsonl', lines=True)\n",
"test.head()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Precisamos usar o mesmo separador seguindo o `prompt` que usamos durante o `Fine-Tuning`. Neste caso é `\\n\\n###\\n\\n`. Como estamos preocupados com a classificação, queremos que a temperatura seja a mais baixa possível e exigimos apenas a completion (conclusão) de um token para determinar a previsão do modelo."
]
},
{
"cell_type": "code",
"execution_count": 71,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'From: gld@cunixb.cc.columbia.edu (Gary L Dare)\\nSubject: Re: Flames Truly Brutal in Loss\\nNntp-Posting-Host: cunixb.cc.columbia.edu\\nReply-To: gld@cunixb.cc.columbia.edu (Gary L Dare)\\nOrganization: PhDs In The Hall\\nDistribution: na\\nLines: 13\\n\\n\\nThis game would have been great as part of a double-header on ABC or\\nESPN; the league would have been able to push back-to-back wins by\\nLe Magnifique and The Great One. Unfortunately, the only network\\nthat would have done that was SCA, seen in few areas and hard to\\njustify as a pay channel. )-;\\n\\ngld\\n--\\n~~~~~~~~~~~~~~~~~~~~~~~~ Je me souviens ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\\nGary L. Dare\\n> gld@columbia.EDU \\t\\t\\tGO Winnipeg Jets GO!!!\\n> gld@cunixc.BITNET\\t\\t\\tSelanne + Domi ==> Stanley\\n\\n###\\n\\n'"
]
},
"execution_count": 71,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"prompt=test['prompt'][0]\n",
"prompt"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"' hockey'"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ft_model = 'ft:davinci-002:personal:eddy-binaryclass:86OuN8we'\n",
"\n",
"res = openai.Completion.create(model=ft_model,\n",
" prompt=test['prompt'][0] + '\\n\\n###\\n\\n',\n",
" max_tokens=1,\n",
" temperature=0\n",
" )\n",
"\n",
"\n",
"res['choices'][0]['text']\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Para obter as `probabilidades de log`, podemos especificar o parâmetro `logprobs` na solicitação de `completion` (conclusão):"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
" JSON: {\n",
" \" hockey\": -3.5120327e-05,\n",
" \" \\n\": -11.312534\n",
"}"
]
},
"execution_count": 37,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"res = openai.Completion.create(model=ft_model, prompt=test['prompt'][0] + '\\n\\n###\\n\\n', max_tokens=1, temperature=0, logprobs=2)\n",
"\n",
"res['choices'][0]['logprobs']['top_logprobs'][0]\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Podemos ver que o modelo prevê que o `hockey` é muito mais provável do que o `baseball`, o que é a previsão correta. Ao solicitar `log_probs`, podemos ver a probabilidade de predição (`log`) para cada classe."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Generalização"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Curiosamente, nosso classificador ajustado é bastante versátil. Apesar de ser treinado em e-mails para diferentes listas de e-mail, ele também prevê `tweets` com sucesso."
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"' hockey'"
]
},
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sample_hockey_tweet = \"\"\"Thank you to the \n",
"@Canes\n",
" and all you amazing Caniacs that have been so supportive! You guys are some of the best fans in the NHL without a doubt! Really excited to start this new chapter in my career with the \n",
"@DetroitRedWings\n",
" !!\"\"\"\n",
"\n",
"res = openai.Completion.create(model=ft_model,\n",
" prompt=sample_hockey_tweet + '\\n\\n###\\n\\n',\n",
" max_tokens=1,\n",
" temperature=0,\n",
" logprobs=2\n",
" )\n",
"\n",
"res['choices'][0]['text']\n"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'Copyright'"
]
},
"execution_count": 43,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sample_baseball_tweet=\"\"\"BREAKING: The Tampa Bay Rays are finalizing a deal to acquire slugger Nelson Cruz from the Minnesota Twins, sources tell ESPN.\"\"\"\n",
"\n",
"res = openai.Completion.create(model=ft_model,\n",
" prompt=sample_baseball_tweet + '\\n\\n###\\n\\n',\n",
" max_tokens=1,\n",
" temperature=0,\n",
" logprobs=2\n",
" )\n",
"\n",
"res['choices'][0]['text']\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "venv_Classification",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
},
"orig_nbformat": 4
},
"nbformat": 4,
"nbformat_minor": 2
}