Branching out of the Notebook: ML Application Development with GitHub

Greg, Melitsa, and Chris build a Stable Diffusion image generator with FastAPI, then add an image-to-image feature using Git branches and pull requests. They show how to test endpoints locally, commit code, open a PR, and merge changes. The workshop covers real development workflow, not just notebooks.
Questions this video answers
July 2022.
Port 8000 (localhost:8000).
Chapters
Foreign.
Hi everyone and welcome to Branching out of the Notebook ML application development with GitHub. My name is Greg Lochnane and I'm leading the product and curriculum team at 4th Brain. We appreciate you taking the time to join us for this event. I can see that we have people joining us live from all around the world. Good afternoon. If you're near me, I'm in Ohio, in the US or for the rest of you, good morning, good evening, or thanks for staying up. Wherever you're joining us from, we're glad to have you. Today, our interactive demo event is a workshop that represents a bit of a follow on to our recent Beyond Jupyter notebooks, MLOps environment setup and first deployment workshop that we presented in September. Here again today, we're still imagining that it's our first week on the job and this time we're aiming to use code for from an existing machine learning web application to deploy a state of the art text to image diffusion model. We're also going to use Git branch development to add an additional image to image feature to our app and we'll use GitHub to create and review a pull request before pushing our new application into production. If you have questions during the workshop today, please please follow the slido link in the description box on the YouTube page. We encourage all of you, whether you have specific questions or not, to click that link so that you can check out the questions others have asked and upvote your favorites. We'll do our best today to answer as many questions as we can during the Q and A portion of the event, so let's get into it. Without further ado, I'd like to bring two of 4th Brain's best machine learning engineering instructors up on stage with me so that we can kick off this event as a team. Melitsa Svetkovich and Chris Alexiak welcome both in real life, Melitsa has been an active organizer in the startup world and feels passionate about startup communities. By day she is a data scientist and outside of work she is really passionate about the outdoors and trekking. Chris is an instructor at 4th Brain as well as a machine learning engineer working on improving communication using natural language processing. And so for today's event we're going to have Malitsa play the role of a machine learning technical product development lead and Chris will be our machine learning and operations engineer. We're going to go ahead and dive in right now. What are we going to cover? We're going to cover first of all what it looks like to use these Couple of libraries that will be key to us today to prototype a text to image ML application. And then we're going to look at how to add image to image capabilities in the form of a brand new feature that is created and merged into our application using branch development. So first off, we're going to prototype this text to image ML app using the state of the art diffusion models library from Hugging Face called Diffusers. Now Diffusers was released in July of 2022 and really this is all about automating creativity. This is what we're hearing a lot about out on social media out in the market today. Now what does this mean? Well, in practice, for this, for this text to image modeling, what it means is taking some text, for example Pikachu dining with a view to the Eiffel Tower and creating an image automatically. So this is a very popular one from the French hugging face. And this is one that we used actually our application directly to create. So Pikachu's there, he's getting ready to eat right by the Eiffel Tower. There are some other diffusion models that we can leverage from hugging face as well. So currently when we talk about automating creativity, we're talking about generation. So this is a text to image generation model. There are three text to image generation models on hugging face. Today we're also going to do an image to image text guide guided generation model of which there is only one on hugging face. Today there are a couple of really cool types of models called unconditional image generation and unconditional audio generation as well. This means that rather than provide text or additional context to an image or to audio, what we're doing is we're simply using using data to train a model and then to generate pieces of audio or to generate images. Last but not least, there is a text guided image inpainting feature that's currently in the experimental phase, but that you can play with yourself and is pretty cool on Hugging face as well. It gives an image, it provides a mask and you also give it some text to change that image very dynamically. So we'll drop the link in the chat below if you want to go ahead and play with that in a Google Colab notebook. We'll be using the Hugging Face libraries. In addition, we'll also be building an API. We'll be building an application interface using Python to our machine learning application. And this is where we heard in the last event, fastapi is really the application framework that you want to learn. If you're going to learn One today. It's been growing at a rapid clip since last year. It looks like the deep learning audience is choosing fastapi more and more all the time and we even had the Fast API creator comment last time which was really cool. So definitely we're going to show you a lot more details on fastapi today. With that, I'm going to go ahead and kick it off, give it over to Melissa and Chris so that we can take a look at how to build this thing.
Melitsa yeah hey Chris, okay, let's look at the app that we created using stable diffusion text to image mode from Hugging Face Diffusers library deployed using FAST API. Can you walk us through the current version of the app with a single feature? The code especially focusing on a Hugging Face Diffusers and Fast API and the architecture and the details of the app deployment. Then after that let's talk about adding some additional functionality to the app and adding a second feature. We want to collaborate in GitHub and especially we want to use the pull requests. Also. Chris, can you use the command line interface for the repo management and write the app source code in the VS code?
Yeah, absolutely, no problem. Melitsa the first thing that we're going to do to get started would normally be to clone this repository using ssh. So that's Secure Shell. If you haven't heard about Secure Shell, we talked about it in our previous event called Beyond Jupyter notebooks, MLOps environment setup and frame first deployment and if you didn't catch that, we'll drop a link right now. I've already cloned it, but if you want to follow along, we're also going to drop a link right now. That shows you the repo that we're going to be working from so that you can follow along as we go through this. Like I said, I've already cloned this using SSH so we can see it here. I'm going to CD into the local repository. Once I'm in the local, the first thing I'm going to do is just a git pull origin main to make sure that we're up to date. Looks like we are and that's great. Since we're up to date, I'm going to go ahead and open code using the command code that's going to open code in our present working directory. Press enter and here we go. It's code. I'm going to walk through the structure of the repository. First up on the left hand side in the explorer we can see that we have our repository. We have our v1 gitignore license and read me pretty standard stuff there. We're going to open our V1 and we're going to see that it has the app, it has the model. These are the weights that we've downloaded locally. Has a Docker file so we can containerize the application. It has some helper functions as well as the requirements. Txt. So let's take a peek at the app and see what's going on in here. First things first, you see that we're doing a bunch of imports. We have all of our imports here. We are going to use primarily FAST API as well as the Diffusers library from Hugging Face. That's going to let us do everything that we need to do. Basically we do some additional imports for things that are going to help us to achieve our goals. But the biggest one to focus on in this section is the Stable Diffusion pipeline, which is using the stable diffusion model available on Hugging Face. The first thing we have to do is instantiate our FAST app. We do that using this straightforward line of code here. We just say that, hey, this app object is going to be a fast API object. Fast makes it very straightforward to to create web apps, and so that's why we're using it today. The next thing we have here is this helper function that's going to tell our program to either use CUDA, if CUDA is available. CUDA here basically means gpu and it's going to let us just iterate through these images much faster. So we're going to be able to have faster inference if we're using our gpu. But if no GPU is available, of course we can just use the cpu. This helper function makes it so that we don't have to choose or hard code that choice. Now we enter the meat of the application, which is we're going to create a fast endpoint by using this handy notation. This is what's called a decorator. And what it's doing essentially is it's wrapping this function here in a bunch of additional code. Now, the decorator notation in Python is really helpful because it lets us have all that additional code without having to write it or without having to surround our function. So it's very handy. You'll see that we use this symbol to indicate it's a decorator and then we're using the app post. So this is our Fast API app. And then we're creating a post endpoint and we're naming it text to Image. So the difference between Post and get, in simple terms is that a post endpoint is going to expect us to send it something and then it will return a response versus like a get endpoint which would just return a response if we pinged it. Now we have the actual work function here, which is this text to image function. It accepts a text and it expects that to be in a string. Then we have our device. We just use our helper function to get that. Then we have our model. Our model is the We've already downloaded the weights from Hugging Face and we have them locally over here in this model folder. The reason we've done that so we don't have to download the weights every time that we that we run this endpoint. So it helps speed things up. Additionally, we're loading this pipeline since Hugging Face has created an amazing pipeline for us to use so that it's very straightforward to get the result we wish. Then we're going to cast that pipeline to our device. So this is whatever device it finds. After that, all we need to do is we need to run our pipeline on the text prompt. We're going to get the 0th image or the first image and we're going to save that into our image variable. Afterwards we need to do some post processing to put it into a format that works with swagger, fast APIs front end. And then we are going to do some lifecycle management in the end point. The reason we're doing this is because you'll notice that we're actually getting the pipeline in the endpoint. The reason that we've decided to do this is just to make the demo more accessible to people so you don't have to have huge resources to be able to run it. But because of that, we want to make sure we're doing some lifecycle management to make sure that we're not using too much of your resources. Lastly, of course, we are going to return our image to Swagger. We return it in the format it expects and we tell it what it should look like and Fast does the rest. It's an incredible platform. The last piece of code here, just some boilerplate. If name equals main, that means when we run the file itself, this is going to run. We're going to use UVicorn, an ASGI server, to run our app, host it on our local host, and then run it on port or expose on Port 8000. So all of this comes together to let us use that application and we'll stop with Greg for a quick check in.
Wow, Chris, that was awesome. You really walked us through a ton of details there. Did everyone catch all of that? Chris talked about doing parallel processing on GPUs with CUDA versus using CPUs. He talked about what a Python decorator does and how it can wrap other functions. He talked about doing lifecycle management and emptying the cache at the end of his application. He talked about deploying on a UVicorn ASCII server. And he also talked about swagger. Swagger has roots to the Open API specification, which allows for a standard interface Description of of HTTP APIs. And we heard a little bit about HTTP commands as well. There is so much good stuff to dive into here, and we look forward to bringing you lots of content in the future that will allow us to do so properly. But for today, we're going to go ahead and see how this thing works. We went and we saw Pikachu dining with a view to the Eiffel Tower. Now we're going to see Chris's app directly work the way you might use fastapi and see what we get when we try to create a striped horse. Chris, back to you. Let's check it out.
Thanks, Greg. Yes. Now we're going to go ahead and test our app locally just to make sure it's working how we expect. The first thing we need to do is just CD into the app and we're going just going to zoom in a little bit here for you guys. We're going to make sure we're in our app. PY is in our present working directory. We can see that it is using the LS command. Now all we have to do is Python app PY press the enter button. That's going to run that boilerplate. We talked about that if name equals main, which is going to set this uvicorn running. Now you'll notice that there's a link here. We could control click this link or we could copy and paste the link. What I'm going to do instead is I'm going to head to my browser and I'm going to use local host 8000 docs and this is going to bring us to Swagger with our endpoint. And look at that, we have it right here. This is the magic of fast. In order to test this endpoint, what I'm going to do is I'm going to go ahead and click on post text to image. I'm actually going to drag this screen to the right here so that we can see what our back end is doing while we look at the front end. Once we've opened the endpoint, we can click try it out and we can enter prompt. So I'm going to enter a striped horse and we're going to click Execute. When we do that, we can see that Cuda is available. This is going to use my GPU to run inference. We're going to use the basic default BERT Basic tokenizer. You can see it working here. It's chewing through iterations and it'll give us an output successful output. We scroll down and we see basically a zebra, which is what we wanted to see with a striped horse. That is what it looks like and that's how our app is working. Back to you, Greg.
Chris. So cool. It's really cool to see that thing working in real time. Accessing the Swagger UI docs from the back end like that. Now we're going to look at how we're going to think about adding our image capabilities when we consider what we've done with our text to image first application created Pikachu by the Eiffel Tower. What we're going to go ahead and do now is we're going to see if we can take our image that we just created, add some additional text. For example, let's say Pikachu and Charizard enjoying the meal together and see how we can actually create a brand new image. It looks like Charizard is pretty excited. Pikachu, not so much. This reminds us of how complicated and difficult prompt engineering sometimes can be. We wanted them to be enjoying the meal together, but maybe we need to be a little more specific and detailed and nuanced in our application of our machine learning application. Let's go ahead and think about how we're going to add this feature. The first thing that we need to understand in broad strokes is branch development and branch development. First off, as we start to build this app, the way to think about it is we're working from the main branch or the trunk of the tree, so to speak. Then as we add a new branch, this is our new feature. So in our case, when we have our text to image, that's the trunk of our tree. And when we add our image to image with additional text generation feature, that's our feature branch. So let's see what the process looks like for branch development in general. Generally we'll have some sort of working repository that's sort of our trunk. And what we do is we want to pull that down to our local repo our own machine so that we can work within our MLOps dev environment. We may want to go ahead and add an additional feature, an additional branch to that main trunk in our local environment. At which point we want to push it back up to that same working repo that now has the additional branch that I coded on my machine. What I can do then is I can make sure that whoever's job it is to review the code knows they need to come pull it and review it. That's called a pull request that I'm going to create as the person that just pushed back up to the working repo. And this is generally where the technical lead in our case Melitsa, is going to come in and review that pull request. Upon successful review, that pull request gets merged into the production application that we now have, which you'll see is free of additional branches. So we're merging back into main. When we do the merge. Melitsa, can you walk us through the details at the tactical git command line level for how we accomplish all of that?
Yeah. Okay. So to make a copy of this repository onto our local machine so that we can actively make changes to it by adding our own code or documentation, we use the command git pull. After we get pull, we can start working in our local repository that exists only on our local machine and not anywhere else and not on the Internet. So now we have the latest version of the remote repository locally, we need to understand branches and how branching works. So let's say that our app is used in real time by clients or customers. Usually the code for this live version is located on the main branch or this tree trunk. To give some intuition, let's get back to our stable diffusion app and this text to image feature in our app that is published in fastapi is part of our main branch. So far we pulled or copied the remote repository locally. The next step is in adding this new feature, is making changes to our app. And we're going to do that by adding this image to image features and sharing these changes with the collaborators. We are going to do that by first creating a new branch. This is going to make sure that the code that we use on our main branch and that might be live is not going to be broken or affected in any way by our work in case we have any errors or bugs in the development process. The important part here is to create and check out a new branch. To do so, we're going to be using this git checkout command. This is not the most intuitive git command you would think. Well, maybe in order to create a new branch, I should be using Git branch command. But that's not the case. Git branch command is reserved for listing all the existing branches. Instead, what we want to do is create and check out the new branch. And the command that does that is Git checkout command. It is important to check out the branch so that we can actually save the work that we're doing. Another important thing is that we can always switch from the newly created branch back to the main branch very easily. Back and forth. The final step after we check out the branch and added our code and we added our new feature, the final step before we create that pull request is to save our changes. This part is called staging our changes in preparation to push them. It is a three step process. Step one is Git Add, step two is Git commit and step three is get pushed again for some intuition. Step one, Git Add means telling Git what changes we made and prepping it for commit stage. It is kind of like saying, hey, I made these changes and I'm letting you know before I save them. Step two, Git Commit saves these changes locally. Usually we have a particular message with a commit or a snapshot. And that way we can easily understand if we look back to our commit history, hey, this is what we did at this point of our development by this looking into this particular snapshot or a message. Step three is Git Push and Git Push pushes or saves these changes that we made to our local repository, to the remote repository. So now all of our collaborators can see this second feature that we did work on and the branch that we created. The final thing that we want to do, we want someone to review our code to make sure that there are no errors, there are no bugs, or maybe something is missing in our code. And we will do that by making a pull request in the browser. Chris, can you show us how it's done?
Yeah, absolutely. You bet. Thanks, Melitsa. The first thing I'm going to do is I'm going to go ahead and I'm going to add the new branch. Melita said she wanted this on a new branch, so I'm going to go ahead and do that. Before I do though, just to be sure, just make sure we're up to date. Looks like we're good. I'm going to clear the screen so it's easy to see what we're doing. The first thing I'm going to do is git checkout B and I'm going to add the name we want our branch to be. I'm going to call this A feature branch and I'm going to call it Image to Image. So basically what this is saying is it's saying we're going to check out a new branch and this branch is going to be called Feature Branch, Image to Image. So I just go ahead and press enter and we can see that we've switched to a new branch. Feature Branch, Image to Image. I'm going to go ahead and I'm going to make sure we're on that branch being extra careful by typing the command git branch and we're going to see that we are indeed on the feature branch. We're no longer on main. You can tell because it's highlighted and there's this sweet asterisk. So that's how we know for sure we're on the right branch. Now that we're on the right branch, I'm going to go ahead and make the modifications that Melissa requested to the application. I'm going to launch VS code by going code again. Once we're in code, I'm going to add the pre written endpoint that we came up with. Just to make sure we're saving everybody some time, I'm going to go ahead and add it here. You'll notice that I created a new post endpoint this time called Image to Image. You could just add and commit at this stage, but in order to be extra sure that everything's working the way I hope I'm going to do a little bit of local testing again just to make sure that it's working. Going to go ahead and close VS code. I'm going to CD into our app again, making sure that our app is in our present working directory. Once I'm here, I'm going to run Python app PY to run the endpoint. You'll see again that it's running on localhost port 8000. Again we could control click this link or copy and paste it. I'm just going to head over to the browser and I'm going to type local host 8000 docs press enter. You'll notice this time that there are two or there is a new endpoint. So there are two total. And there's a brand new endpoint called this Image to Image endpoint. I'm going to open it and I'm going to click try it out. You'll notice here that we require the prompt still, but we also require an image. And this is the Image to image idea. The image I'm going to be using today is this beautiful picture of a boat in a Harbor with a castle. However, I would like it to be even more beautiful. What I'm going to do is I'm going to make the prompt a boat in a harbor with a castle. I'm going to add the image itself and then I'm going to press execute. This is going to help test our endpoint again. You can see we're using Cuda. It's using my GPU to do the inference. We are again using the BERT basic tokenizer default and you can see here it's chewing through those iterations and it will give us some result if we scroll down. We will see we have didn't misunderstand too bad. A boat in a harbor with a castle. That is a boat with a castle. Additionally, there's a castle over here. I think all in all, this is working the way I expect it to. If my prompt engineering needs a little work, that's fine. I'm going to go back to the terminal here. Satisfied with the app the way it's working. I'm going to go ahead and clear it just so we can see a little bit easier. I'm going to do a get status just to see what I'm working on and what branch I'm on. You can see that I've modified the app PY and that's it. That makes sense because I did do that. I'm on the feature branch image to image. What I'm going to do now is I'm going to add all of the changes I've made using git add. Again, it's only one change, but I'm confident that there's nothing else changed. Git add. That's going to stage all of those changes. Now that I've staged those changes, I'm going to commit the changes which with a helpful message added the image to image endpoint and pressing enter. You can see that I've made this commit. Now I'm going to push those changes to the remote. Now, you can't just do git push origin main here because we need to make sure that we tell the remote what branch we want this on.
So.
So we're on a branch that the remote doesn't yet know about. Our local has it, but the remote doesn't. So we're going to use this command git push setupstream Then we're going to say origin, which is our origin remote. And then we're going to add the branch feature branch image to image. This is going to tell GitHub that we're pushing this to a New branch. We go ahead and do that. You can see that it pushes like normal. However, Git is smart enough to know that we have created this new branch and so it has added the ability for us to quickly navigate to the pull request by providing us this link, which again, we could copy and paste into our browser or we could just control click. So I'm going to go ahead and hold control and left click the link. You'll see in our browser that we have it set up. We're in the pull request page now. We could also navigate there by just going to our repository and then we could go to our branch and we could go to our feature branch image to image and we could click New pull request. I'll try that as well. Again, what we're going to do here is we're going to add some helpful text so that whoever's looking at this pull request knows what's going on. So I'm going to add something that says added the image to image endpoint tested. It's working. I'm going to go ahead and create the pull request now and then instead of merging it myself, like Malita talked about. What I'm going to do instead is I'm going to have I'm going to assign a reviewer so someone can look over the code, make sure that it's good, and then merge the request after we've had two sets of eyes on it. The way I'm going to do that is by clicking the reviewers cog wheel here and selecting Melitsa as my reviewer. Hopefully she gets that request soon and she's able to review these changes.
Yeah. Okay, let's see. See what Chris did. Okay, so here in the browser, on the main page of our repository, we have the stab pull requests. So this is how we're going to be reviewing pull requests in the browser. We're going to go ahead. This number one indicates the number of open pull requests that we have at the moment. And in the tab we can see the list of the pull requests. So here we see this. Added the image to Image Endpoint that creates Chris just created. I'm going to go ahead and open this pull request and start my review. So the tabs at the top, this conversation tab is kind of like a summary of everything that is happening on this pull request. So Chris just made a commit and he added this commit message. And then after I add my comments, the comments are also going to be visible here. This is also easy to be used as a going back and forth and collaborating on an issue. So let's say that I make a comment on something and it requires an action on part on collaborators part. A person can go ahead and go in there, make another suggestion or bounce off some ideas and is made to be collaborative tool that is our conversation. Then in the commits we can see one commit that Chris made. In case that we keep going back and forth and multiple commits are made, this number would change. We're going to skip checks for now and go to the files changed. Files change is where I'm going to be reviewing the pull request and Chris's code. So briefly to walk over this view right here we again see this cog wheel. It gives us different views. So right now we're using this unified views, which is what I'm going to be using to review the pull request. What it does, it gives me the old code with the added code kind of like one after another. Or I can view it in a split view which gives me more a side by side view where old code is on one side and that the new added code is on the other side. I can also have I There's also an option for me to notify the person who made a pull request that I viewed this or I can add edit a file and add a code or comments or any documentation directly in the file right here in the browser. I'm not going to be using that functionality right now. What I'm going to be doing, I'm going to be adding comments using this plus sign, this blue plus sign that you can see next to the the number line that the the line number. So here at the line 46 we have this piece of a code code that has already existed that was part of our previous feature. And just a reminder that the goal of this, of this pull request and the new branch that Chris created was to add the second feature, this image to image. Route to our already existing text to image. We also want it to be able to in addition to text prompt, upload the image as well and then using the text prompt output the new image or improve the image that we inputted. Okay, so let's review this code and again this plus sign is going to give me availability to add comments. So here we can see in the line 49 that Chris added this post endpoint the image to image endpoint to our app and then in the definition of our function we can add the text prompt as a string and we can also upload the image. Okay, here we're calling our device instantiating a GPU or CPU and this is the the model itself here, unlike our previous feature, we are using stable diffusion image to image pipeline and we're again loading this from the pre trained model in our repository. Then the important part is right here. The first thing that we're going to do, we're going to convert this image, this preloaded image to the RGB and we're going to do some resizing. Then the next thing, this line 59 we're going to load the first image from this prompt and the uploaded image in the line 61. What Chris did, he converted the image to a NumPy array. In 62 and 63 we're using OpenCV. We're using first we're converting color from RGB to BGR and this is just something that OpenCV requires us to to do when encoding the image. In order to encode the image we need to convert from RGB format to BGR format. And the last thing we're going to do we are going to be encode and save our image as a PNG format. Then the rest is pretty much a similar thing that we did in our first feature. This all looks good to me. There is nothing seemingly wrong to the code and I know that Chris did some testing on this as well and it is working as desired. I am not going to retest it again again. So I'm just going to demo how I would leave comments in case there is something wrong with the code or that I have maybe some suggestions on how to improve the code. I'm going to click on this blue plus and a new prompt is going to pop up. I can leave a comment here for right now I'm just going to say no suggestions here. I have many options. I can edit and modify text in case there's a really long comment. You know, it can. I can make something pop with making it bold or italic or I can also make code suggestions. I can add code itself, I can add links. So really it is a full on markdown. It has all markdown capabilities. And here I can either cancel it and be like oh never mind, I changed my mind. I can add it as a single comment or I can start a review, which is what I would want to do when reviewing a comment comment and making multiple suggestions. Now here at the top right we can see this. Finish your review that came up number one indicates the number of comments that currently exists until I hit this. Finish your review. I can go back and I can edit or delete my comments. I can add multiple comments to it and Add another comment to it again. Now the number has changed. I can go ahead and go back and edit the first initial comment or I can delete everything altogether. So I'm going to leave this one comment right here so that we can see how we can merge the branch. If I go and hit finish your review, I'm going to leave one final comment to this. What I'm just going to say is great job, Chris. I can comment on it. I can approve right away if there is nothing wrong, which is kind of like what is expected to do right now. But in order to showcase the whole process, I'm just going to make a comment or I can request changes. If I request the changes, the pull request would go back to Chris and he can go and make the suggestion, make the suggested changes or review what I suggest that it and make his own. Make his own suggestions and go back and forth again. Okay, I'm going to submit this review and it's going to bring me back to the conversations. Now this number is two. We can see the Chris's commit message right here. And now we can see my comment as well. Usually the way this would work. If I'm making any suggestions to the code, Chris could reply here. And then finally we can resolve the conversation once everything looks good and the code is ready to merge. So that is what I'm going to do. I'm going to resolve my own conversation and then now we can see that this branch is ready to be merged. What I'm going to do to go back to that tree trunk analogy that we had, we had that tree trunk and our main branch and we had this new branch and now we're going to merge or kind of cut off this new branch. Going to go ahead and do that. I'm going to confirm the merge and it's going to give me GitHub is automatically going to give me the option to delete this branch, which I'm also going to go ahead and do. And that is it. This ends my pull request. There are no more pull requests right here. If we go to the pull requests list and awesome job, Chris. Okay, Greg, I'm going to let you finish it up.
Awesome. Great work, Melitsa and Chris, you really nailed it on the app development, the application review and getting that pull request handled and merged in review. What we just did is we saw the working repo with that text to image diffusion model app being taken down, pulled down, cloned into Chris's local repo. Then Chris went ahead and added that image to image Diffusion model feature on the application. He then pushed back up to the working repo this new branch with the existing application and he created a pull request. That pull request was then reviewed by Melitsa, the product dev tech lead and she said, hey, everything looks good. We're going to merge it back and we're going to create just now this main branch, this main trunk with no additional branches. She deleted the branch so that now we have all the code in one one production application. Very cool. Awesome stuff both of you. So you know, today what we saw is we saw just how awesome and powerful that diffusers library is. Whether you're doing image to image, text to image or even more things than that. We saw prompt engineering. It was potentially kind of still a black art. Maybe we'll see prompt engineers in the future. We saw Fast API as the leading web application framework, at least in terms of growth over the last year or so. We talked about decorators and ASGI servers and swagger and cuda. We talked about a whole lot of things that there's a ton more depth that we could go into in the future. And we got an introduction to branch development, from cloning and pulling to creating branches, checking them out, adding, committing and pushing back up to working repos. We talked about pull requests and reviews and ultimately we talked about merging code into production environments. So with that, I think that if you took all that in, you're just about ready to start branching out of the notebook. You'll notice we didn't even see a jupyter notebook today. We were working directly in Python and VS code and our MLOps dev environment that we set up last time. So branch out and for more resources to help you do that, from setting up your GitHub to do secure shell cloning. We dropped that link earlier to the tutorial that we went over today. You can go through, you can try it out yourself. Also dropped that earlier to playing around with the new experimental stable diffusion inpainting for yourself. Even take a look at these exact slides. We'll drop the link for these slides to you in the chat right now. So with that, thank you so much. Any questions that you have, please add them to slido. Let's see if we can get some more upvotes going. Reach out to Chris Melitsa or myself for feedback, comments, questions or anything else. So with that I'm going to stop screen share, bring Chris and Melissa back up on stage here and we're going to go through some Q and A. So really excited. Great job both of you. That was awesome. And we're going to kick it off with the first question that got the most upvotes 15 and this question is how do you version control machine learning models? Say you make changes to a hyper parameter.
What then?
Chris, let's kick it off with you.
Yeah, so that's a great question and one with a lot of different answers depending on who you ask and where your company is and what kind of platforms you're using. Typically though, you'll use a tool to do that, such as DVC or version control available through your cloud platform. So Vertex AI has model versioning. AWS also has model versioning. It is absolutely a critical piece of the puzzle. So if you are iterating on models, you do want to make sure that you have some kind of model versioning. Typically that's something that's relegated to one of the many impressive tools that exist right now.
Very cool. Melissa, do you have anything to add to this?
Yeah, I didn't go old school since Chris mentioned all of these tools that you can use. Another thing that you can do is very much go old school and open a just have a spreadsheet of all the times that you ran your model with all of the hyper parameters and then just save it as a pickle file or whatever you want to save it as and pretty much share that with your team and have every single time you run a model, every single time you change anything, you can, you know, follow the metrics, you can follow any hyper parameter you change. So you just go old school depending on what you're doing and do it that way as well. If you're, especially if you're like early team that you're just starting out and you don't want to spend resources or you don't want to add additional tools to learn, just go OG Love it.
Love it.
Yeah, go manual before you go magical. And you can go auto magical with some of these model versioning tools today. We've seen that and those will continue to become more and more popular. But you can't beat a spreadsheet or maybe even a piece of paper right next to your desk. Just make sure that you are version controlling your stuff. Okay, next question. Nine up votes. Which frameworks are more important to learn when starting out in ML today? Web app frameworks like Fast API or modeling frameworks like TensorFlow Melitsa, over to you. What do you think?
Yeah, I think that would depend 100% of where you want to go. I think that those are two kind of. Well, it depends Again, it depends on a size of the company that you're working for that if you're working in a very small team, let's say 10 people, you have a PM, you have some kind of manager and then you have one or two engineers, it is highly likely that you are going to be using, you're going to be kind of like more of a full stack machine learning person where you're going to be using all of these tools and you're going to have to know everything. On the other hand, if you're working for a mid size or a very massive enterprise corporation, chances are that you're probably going to be using, you're going to be using a single thing, you're specializing in a single tool. So it really depends on, I'd say your personal ambitions and desires, where you want to go into your, with your career. So if you want to go more into a ML ops side and focus on a single thing, probably do something like web app frameworks. On the other hand, if you want to focus more on a modeling and all the cool things happening in that world right now, definitely focus on a modeling framework.
Very cool. Chris, any additional color you want to add here to this question?
Yeah, I would say in order to give yourself the competitive edge, you too, like our models, must use parallel learning. So it's really important to learn the modeling framework next to something that makes it do its job. I think that a lot of people get stuck in the modeling weeds, but I think what a lot of employers are looking for is someone who's able to turn that into something that's actionable and impacts the world. And so learning these things alongside each other is going to give you a huge leg up. When you're creating your first simple models and you're putting them in your first simple web framework, you're going to be way more set up for success when you go to creating your first complex model in your first complex web framework. I think just like our models, we want to use parallel learning.
If I can add just one thing since Chris, Chris and I are instructors together and we teach classes together, I do want to add one thing that Chris always says to our cohorts. I'm going to let Chris add to it. But he always likes to remind. A great way to learn a new tool that is super simple is whatever any model you make, no matter how simple or complex, just dockerize it, just containerize it right away and you can start from a super simple model and your docker file is going to be simple. And then build up from there. It's just an easy thing to do right away. This is Chris's advice, by the way.
Yes. Well, since we went there, Chris, we did have a question that I think you can probably help out with here. It was, do you manage virtual environments for Python while developing these containerized apps?
Yeah, you bet you do. Yes. If you didn't catch our last event, we talked about tools like conda. I use conda all the time to manage my environment. It's an impressive tool, not just because it can handle the environment side of things, but also it can handle the Python versioning. It can do it all, I would say. Yes, absolutely.










