 The model that we just trained is still being evaluated. It's generating samples for our evaluation dataset. This might be a good time to take a look at our evaluation code. In this case study, we will use the concept of LLM as a judge. That means that we will provide an advanced LLM like GPT-4, the instructions that we need to respond to. And we will provide two responses. One will be from our baseline model. This is what we are evaluating against and we're trying to improve on top of the baseline. And we will provide the instructions from a candidate model. And because we are using model registry, we'll pull both the baseline and the candidate from model registry based on aliases. So let's take a look at this code. As you can see we are starting with a configuration object and we're providing the model that we will use as a judge. So in this case, it's GPT-4, specifically version 0.6.13. We're providing it with a system prompt. And the system prompt says you will be presented with a choice of model A and model B response for an instruction. The response should follow the instructions and use the provided context, if there is some. And we're using the chain of thought prompting. So we're asking the model to think step-by-step, which response is better, provide a reason why, and then asking it to answer with a choice if model A or B or equivalent is better. We are providing it with a baseline in the candidate model names that we will use to parse our our data we can limit evaluation to certain number of samples we're again providing our weights and buses project entity and again for your use case you may want to change that entity to your either personal entity or the team that you're working in and and we're also providing it specifically the aliases of our of the model we are evaluating, so in this case it's our candidate model, and the baseline. And this is something we need to make sure exists in the model registry. So we have models that are assigned both baseline alias and the candidate alias. We will be using Instructor to get structured outputs from our LLM, from our evaluation LLM. And I want to highlight here a great course that we have on getting structured outputs from LLMs that you can also access on the Weights and Bases courses. And there you can go deeper into how Instructor uses Pydantic to get the structured outputs. In this case, we're collecting two fields from our LLM. One is the chain of thought, which is actually the reason why the model selected model A or model B, and then the choice, which is either A, B, or equivalent. Then we have the evaluator class, which takes in the config, it patches the OpenAI client with instructor so that we can get the structured outputs out of the client. And then we're providing it the instructions and the responses from both models, the candidate and baseline. When using LLM as a judge, we need to be careful about some of the biases that LLMs has. And one of the biases is position bias. So sometimes whether a response comes first or second, that might influence the choices of an LLM. And for that reason, we are shuffling the answers randomly. So with enough samples, we will be able to avoid that position bias. So shuffling the answers, we're giving the LLM the system prompt that we already reviewed and the input, which is the instruction, the generation from model A, generation from model B, and we're asking it to respond with a choice. And then there are different metrics that you might use with LLM as a judge when comparing two models. One classic metric is win rate. But I find win rates sometimes difficult to interpret, especially if you account for ties between models. You need to do certain estimation on how that win rate should be calculated. And I like simple metrics. So the simple metric that we will use is whenever there is a tie, we will return a zero score. Whenever the baseline is chosen, the score will be minus one. This is the score for the baseline. It's minus one. Whenever the candidate is chosen as a better response, we'll get a score one. Now, if we average all of the scores across our evaluation data set, we'll get a metric which we will call candidate preference score. And if that metric is positive, then that means that the candidate is better than the baseline. If that metric is negative, that means that the baseline is better. And that metric goes between minus one and one. In the case of minus one, all of the responses in our evaluation set were better for the baseline. In the case of one, all of the responses of the candidate were better. So it's a pretty good metric that is very easy to interpret. The higher the score, the better the candidate. So you can make certain, you can put certain rules. For example, if the metric is above 0.5, that means like we're always switching the candidate for the baseline. If it's around zero, like it means that maybe it's borderline, maybe you need to do some more, some more fine tuning or get a better candidate. And if it's negative, that means strictly that the baseline is better. So that will be the metric that we'll use and we'll send off all of the responses to the LLM via the API client. We'll gather the responses and calculate our candidate preference score and log it into weights and biases. One thing I want to do here and highlight that I like to do personally, I think it's a good practice, is as you store the evaluation results in weights and biases run, I'd like to add lineage specifically to both the candidates and the baseline model and update this in the config. So you will see that I'm using our artifacts API, calling 1db.useArtifact with the evaluation baseline from the model registry. And then I'm taking the path of that model and saving it in my config as evaluation model path. And I'm doing the same with the baseline. And that will make sure that whenever I look at the results from this evaluation, I understand exactly which model was evaluated against which baseline. So I'm downloading the table from each of these models, the evaluation, the baseline, merging the table, passing this to our evaluator that we reviewed, then saving the results into a results data frame, calculating our candidate preference score, and again positive score will mean that our candidate is better, and then also saving the results into a weights and biases table that we can inspect, logging it into a weights and biases both as a table and also storing a CSV file that we can use locally if needed. and also storing a CSV file that we can use locally if needed. So our evaluation run is almost finished. So in the next video, we'll take this evaluation script and we'll try to set this up for running in an automated way based off model registry triggers. See you there.
Setting up LLM evaluation
After training a model, we need to understand how good it is. We will use LLM as a judge method for the evaluation of our models. 

In this session we will use the following parts of the course repo: 
https://github.com/wandb/edu/tree/main/model-management

eval.py code:
https://github.com/wandb/edu/blob/main/model-management/eval.py

Further resources: 
-LLM Engineering: Structured Outputs course with Jason Liu: https://www.wandb.courses/courses/steering-language-models