Integrating a fine-tuned model into my Django-React application issue

I have a feature where the user can log what they’ve eaten for meal and the food data would get passed into to a fine-tuned model I created and the model would feedback to the user the impact it would have on their sugar levels and well-being. After having trained the model using the jsonl file which successfully completed and tested it in the playground. When I include the code in my views.py and test it, i get a 200 response in the terminal, but on the UI its saying “Sorry, I couldn’t provide a response. Please try again.”. Any help here would be much appreciated to help me fix this issue.

On the frontend, the user enters what they had for breakfast for example, fish and chips, and the model would produce an output like shown on the second image.

#views.py
from openai import OpenAI
client = OpenAI(api_key=os.getenv(“OPENAI_API_KEY”))

@csrf_exempt
def get_dietary_advice(request):
if request.method == “POST”:
data = json.loads(request.body)
user_input = data.get(“user_input”)

    try:
        response = client.chat.completions.create(
            model="ft:gpt-3.5-turbo-0125:personal:dietary-advice-bot:9CUENrwC",
            messages=[
                {
                    "role": "system",
                    "content": "This chatbot provides dietary advice for people with type 2 diabetes."
                },
                {
                    "role": "user",
                    "content": user_input
                }
            ],
            max_tokens=150,
            temperature=0.7,
            frequency_penalty=0,
            presence_penalty=0,
        )
        # Extract the advice from the response assuming the last message is the bot's response
        if 'choices' in response and response['choices']:
            advice = response['choices'][0]['message']['content']
        else:
            advice = "Sorry, I couldn't provide a response. Please try again."
    except Exception as e:
        return JsonResponse({'error': str(e)}, status=500)

    # Save the user input and AI advice to the database (assuming this model exists in your Django app)
    entry = UserMealEntry.objects.create(
        user_input=user_input,
        ai_advice=advice

)

    return JsonResponse({'advice': advice})

return JsonResponse({'error': 'Invalid request'}, status=400)


eenshot 2024-04-11 at 13.08.30.png…]()

The React component:

import React, { useState } from ‘react’;
import ‘…/…/sass/PatientDashboard.scss’;
import { Typography, Grid, IconButton, Button } from ‘@mui/material’;
import ArrowBackIosIcon from ‘@mui/icons-material/ArrowBackIos’;
import ArrowForwardIosIcon from ‘@mui/icons-material/ArrowForwardIos’;
import AddIcon from ‘@mui/icons-material/Add’;
import axios from ‘axios’;
import { Dialog, DialogTitle, DialogContent, TextField, DialogActions } from ‘@mui/material’;

const DietaryHabits = () => {
const [selectedDate, setSelectedDate] = useState(new Date());
const [open, setOpen] = useState(false);
const [currentMeal, setCurrentMeal] = useState(‘’);
const [foodEntry, setFoodEntry] = useState(‘’);
const [entries, setEntries] = useState({ Breakfast: ‘’, Lunch: ‘’, Dinner: ‘’, Snacks: ‘’ });
const [dietaryAdvice, setDietaryAdvice] = useState(‘’);

const handleClickOpen = (meal) => {
    setCurrentMeal(meal);
    setOpen(true);
};

const handleClose = () => {
    setOpen(false);
};

const changeDate = (offset) => {
    setSelectedDate(prevDate => {
        const newDate = new Date(prevDate);
        newDate.setDate(newDate.getDate() + offset);
        return newDate;
    });
};

const formatDate = (date) => {
    return date.toLocaleDateString('en-UK', {
        weekday: 'long',
        year: 'numeric',
        month: 'long',
        day: 'numeric',
    });
};




// Function to submit the food entry to the backend
const handleAddFood = async () => {
    try {
        const token = localStorage.getItem('token');
        const response = await axios.post('/api/dietary-advice/', { user_input: foodEntry }, {
            headers: {
                Authorization: `Token ${token}`
            }
        });
        setDietaryAdvice(response.data.advice);
        handleClose(); // Close the dialog
        // TODO: You might want to do something with the advice here, like displaying it to the user
    } catch (error) {
        console.error('There was an error getting the dietary advice:', error);
        // Handle errors here, such as displaying a message to the user
    }
};
// Update food entry state when typing in the text field
const handleFoodEntryChange = (event) => {
    setFoodEntry(event.target.value);
};


return (
    <div style={{ backgroundColor: '#eef0f9', padding: '16px' }}>
        <Typography variant="h5" gutterBottom>
            Dietary Habits
        </Typography>
        <Typography variant="subtitle1" gutterBottom>
            Track and manage your daily food intake to better control your blood sugar levels.
        </Typography>
        <Grid container justifyContent="center" alignItems="center" sx={{ my: 2 }}>
            <IconButton onClick={() => changeDate(-1)} aria-label="Previous day">
                <ArrowBackIosIcon />
            </IconButton>
            <Grid item xs={12} sm={'auto'}>
                <Typography variant="body1" align="center">
                    {formatDate(selectedDate)}
                </Typography>

            </Grid>
            <IconButton onClick={() => changeDate(1)} aria-label="Next day">
                <ArrowForwardIosIcon />
            </IconButton>
        </Grid>



        {['Breakfast', 'Lunch', 'Dinner', 'Snacks'].map((meal) => (
            <Grid container justifyContent="space-between" alignItems="center" sx={{ mt: 4 }}>
                <Typography variant="h6" component="div">
                    {meal}
                </Typography>
                <Button
                    variant="contained"
                    startIcon={<AddIcon />}
                    onClick={() => handleClickOpen(meal)}
                    sx={{
                        bgcolor: 'primary.main',
                        '&:hover': {
                            bgcolor: 'primary.dark',
                        },
                    }}
                >
                    ADD FOOD
                </Button>

                <Dialog open={open && currentMeal === meal} onClose={handleClose}>
                    <DialogTitle>Add Food for {currentMeal}</DialogTitle>
                    <DialogContent>
                        <TextField
                            autoFocus
                            margin="dense"
                            id="food"
                            label="Food Name"
                            type="text"
                            fullWidth
                            variant="standard"
                            value={foodEntry}
                            onChange={handleFoodEntryChange}
                        />
                    </DialogContent>
                    <DialogActions>
                        <Button onClick={handleClose}>Cancel</Button>
                        <Button onClick={handleAddFood}>Add</Button>
                    </DialogActions>
                </Dialog>
            </Grid>
        ))}

        {/* Possibly display the dietary advice here */}
        {dietaryAdvice && <Typography>{dietaryAdvice}</Typography>}

    </div>
);

};
export default DietaryHabits;

The issue is in your chat completion part. However, just as some general advice, and maybe you don’t need this, but may be worth adding a console log in your React component to ensure that the response.data.advice is being sent to the backend with the expected data. Just off the cuff suggestion.

Regarding the issue, your chat completion is off.

‘choices’ is part of the JSON response, so you don’t need to check if it’s there or not. It will be there. If an error is triggered from OpenAI’s side, they will notify you with an error message. You’re searching for the ‘choices’ key inside the value of `response[‘choices’], which contains the index and message keys along with their values (in other words, ‘choices’ in not inside the ‘choices’ object).

Try this instead:

try:
    response = client.chat.completions.create(
        model="ft:gpt-3.5-turbo-0125:personal:dietary-advice-bot:9CUENrwC",
        messages=[
            {
                "role": "system",
                "content": "This chatbot provides dietary advice for people with type 2 diabetes."
            },
            {
                "role": "user",
                "content": user_input
            }
        ],
        max_tokens=150,
        temperature=0.7,
        frequency_penalty=0,
        presence_penalty=0,
    )
    advice = response.choices[0].message.content
except Exception as e:
    return JsonResponse({'error': str(e)}, status=500)

This is a much more natural, standard chat completion.

As another off the cuff suggestion, try experimenting with a more detailed system message, like perhaps an example or explicit instruction on what dietary advice to provide (though I don’t know what your fine-tuning examples are - I wouldn’t want to confuse the model by providing conflicting instructions).

2 Likes

Thank you so much that fixed it. Also, I’ll give a more detailed system message for the model aswell

2 Likes

I’m also trying to dockerize my django application and deploy it on to AWS using Elastic Container Service. When deploying, I seem to get an error saying " ModuleNotFoundError: No module named 'openai'". If you could help with this, that would be great.

I uninstalled openai, upgraded my pip, and reinstalled openai. This my views.py so far.

from openai import OpenAI
client = OpenAI(api_key=os.getenv(“OPENAI_API_KEY”))

@csrf_exempt
def get_dietary_advice(request):
if request.method == “POST”:
try:
data = json.loads(request.body)
user_input = data.get(“user_input”)

        response = client.chat.completions.create(
            model="ft:gpt-3.5-turbo-0125:personal:dietary-advice-bot:9CUENrwC",
            messages=[
                {
                    "role": "system",
                    "content": "This chatbot provides dietary advice for people with type 2 diabetes."
                },
                {
                    "role": "user",
                    "content": user_input
                }
            ],
            max_tokens=150,
            temperature=0.7,
            frequency_penalty=0,
            presence_penalty=0,
        )
        advice = response.choices[0].message.content

        entry = UserMealEntry.objects.create(
            user_input=user_input,
            ai_advice=advice
        )
        return JsonResponse({
            'id': entry.id,  
            'advice': advice
        }, status=201)  
    
    except Exception as e:
        return JsonResponse({'error': str(e)}, status=500)
else:
    return JsonResponse({'error': 'Invalid request'}, status=400)

Can you show or have you checked all the openai import statements you have in your entire application?

I’m guessing you used pip install openai which will install the latest version. The old syntax was ‘import openai’ where as now it’s ‘from openai import OpenAI’ (oops you explained that, apparently I can’t read today)

So if you have any lingering old syntax ‘import openai’ those should be removed. Or is that your entire API function contained in what you provided?

Or you could post your requirements.txt for Docker container, that might help narrow it down too

Yeah i used pip install openai

Here’s my requirements.txt which includes latest version of openai. The docker container uses this requirements.txt to build the image

annotated-types==0.6.0
anyio==4.3.0
asgiref==3.7.2
async-timeout==4.0.3
attrs==23.1.0
autobahn==23.6.2
Automat==22.10.0
bidict==0.23.1
certifi==2023.7.22
cffi==1.16.0
channels==4.0.0
channels-redis==4.2.0
charset-normalizer==3.3.1
constantly==23.10.4
cryptography==41.0.5
daphne==4.1.0
defusedxml==0.8.0rc2
distro==1.9.0
Django==4.2.6
django-cors-headers==4.3.0
django-csp==3.7
django-jazzmin==2.6.0
django-rest-knox==4.2.0
django-templated-mail==1.1.1
djangorestframework==3.14.0
djangorestframework-simplejwt==5.3.0
djoser==2.2.0
drf-spectacular==0.27.0
drf-yasg==1.21.7
gunicorn==21.2.0
h11==0.14.0
httpcore==1.0.5
httpx==0.27.0
hyperlink==21.0.0
idna==3.4
incremental==22.10.0
inflection==0.5.1
jsonschema==4.20.0
jsonschema-specifications==2023.11.2
msgpack==1.0.8
oauthlib==3.2.2
openai==1.17.1
packaging==23.2
pyasn1==0.5.1
pyasn1-modules==0.3.0
pycparser==2.21
pydantic==2.6.4
pydantic_core==2.16.3
PyJWT==2.8.0
PyMySQL==1.1.0
pyOpenSSL==24.0.0
python-decouple==3.8
python-dotenv==1.0.0
python-engineio==4.9.0
python-magic==0.4.27
python-socketio==5.11.1
python3-openid==3.2.0
pytz==2023.3.post1
PyYAML==6.0.1
redis==5.0.2
referencing==0.32.0
requests==2.31.0
requests-oauthlib==1.3.1
rpds-py==0.14.1
service-identity==24.1.0
setuptools==68.2.2
simple-websocket==1.0.0
six==1.16.0
sniffio==1.3.1
social-auth-app-django==5.4.0
social-auth-core==4.4.2
sqlparse==0.4.4
tqdm==4.66.2
Twisted==24.3.0
txaio==23.1.1
typing_extensions==4.10.0
uritemplate==4.1.1
urllib3==2.0.7
wsproto==1.2.0
zope.interface==6.2

Ok that’s definitely the latest or a later version. Question. Are you running a virtual environment? @MJN1

Yeah its called health_env, do you think i should create a new one?

No I wouldn’t think you need a new one. And you said you upgraded pip so that’s not an issue. It’s hard to tell the issue without seeing your environment.

I manually point my Python interpreter to the venv python exe (I’m assuming you’re in VS Code)

(Shift + P, Python: Select Interpreter, and then find the \venv\Python\Scripts\python.exe file and select)

You could also try deleting the Django container and rebuilding the container like this:

docker-compose build --no-cache django

I think one time I had a similar issue, I had to go delete all the pycache files because there was some weird caching issue. And on top of that, for switching over to the new OpenAI syntax, I had some similar issues, it’s just been a while for me to remember.

Sorry if I wasn’t clear - the reason I am asking about your venv and Python interpreter is, if you install openai on a different version of Python than what your venv is running on, then you will have these issues - you are having all the issues I used to have :smiley: but don’t worry, they are figure-out-able. It will prob take more time than you would like because your coding environment may have small differences from solutions online. But don’t worry, the solution is probably right before your eyes.

I actually installed everything using the same version of python and virtual environment. I’ll try docker-compose build --no-cache django.

i selected my virtual environment, i don’t think this will work icl. The issue will still be there

I guess I’m not on my game today. The incorrect installation is being expected somewhere, and imo it’s likely that your pip is looking in the wrong python directory, so some config issue somewhere, but there are definitely other causes. I had the wrong Python version in my Dockerfile once. It’s just really hard to tell without being able to see your whole environment.

I can show you my Django Dockerfile for my gpt app:

# Dockerfile
FROM python:3.11.5

# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# Set work directory
WORKDIR /code

# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
    gcc \
    libpq-dev \
    && rm -rf /var/lib/apt/lists/*

# Install Python dependencies
COPY requirements.txt /code/
RUN pip install --no-cache-dir -r requirements.txt

# Copy project
COPY . /code/

# Collect static files
RUN python manage.py collectstatic --noinput

CMD daphne -p 8001 -b 0.0.0.0 scribe4.asgi:application

For me, the “RUN pip install --no-cache-dir -r requirements.txt” was helpful. Sorry I can’t be of better help atm. Again these are always hard to troubleshoot without knowing or having gone through the setup for your environment.