The best way to design a backend internship project around machine learning inference is to treat the model as a replaceable component and put your effort into the service around it: a strict input contract, a loaded-once model, measured latency and a clear serving mode. In 14 days, one model, one validated endpoint, a latency report and a short design note will show more backend skill than a complex model ever could.
This guide gives Plaksha University students a complete design template, a latency budget method, a batch versus real-time trade-offs table, a worked illustrative example and a 14-day plan.
What the project is, and what it is not
You are not trying to train a better model. You take a model that already exists (a scikit-learn classifier, a small regression model, or a pretrained text model) and wrap it in a Python API that other software can call safely and predictably. The deliverable is a service, not a notebook.
A reviewer reading your repository should be able to answer five questions in a few minutes:
- What exactly can a caller send, and what happens if they send something wrong?
- How is the model loaded, versioned and replaced?
- How long does a prediction take, and how do you know?
- What happens when the model fails or the input is unusual?
- Can someone else run it with two or three commands?
If you are looking for a structured way to do this, the free two-week online internship from CareerSwami offers a 14-day format with an offer letter and a completion certificate after successful completion, and this project is sized to fit it.
Choosing a model that keeps the backend work in focus
Pick a model small enough to run on a laptop CPU. Large models make you fight memory and downloads instead of designing an API. Good choices include:
- A tabular classifier (for example, predicting whether a support ticket is urgent from a handful of numeric and categorical fields).
- A regression model on a public dataset you already know from coursework.
- A small text classifier using TF-IDF and logistic regression.
Save the trained artefact with a version in its filename, such as model_v1.joblib, and store a small metadata file next to it listing the feature names, their order, the training date and the library versions. This metadata drives your validation later.
Free 2-Week CareerSwami Internship
Online, 14 days, with a free offer letter and a free completion certificate once you finish the work. Check with your college that it fits your requirement before you enrol.
Design template: the service contract, one page
Fill in this template before writing code. Keep it in the repository as DESIGN.md.
| Section | What to write | Example entry (illustrative) |
|---|---|---|
| Purpose | One sentence on the prediction and the caller | Return an urgency label for a support ticket |
| Input schema | Field names, types, ranges, required or optional | ticket_length integer 1 to 5000; channel one of email, chat, phone |
| Output schema | Fields returned, including model version | label, score 0 to 1, model_version |
| Error contract | Status codes and message shape | 422 for invalid input, 503 if model not loaded, 500 otherwise |
| Model lifecycle | When loaded, how versioned, how replaced | Loaded at startup; version read from metadata file |
| Latency budget | Target for p50 and p95 per request | p50 under 30 ms, p95 under 100 ms on laptop CPU |
| Serving mode | Real-time, batch or both, with reason | Real-time single plus a batch endpoint up to 100 rows |
| Observability | What is logged and exposed | Request ID, duration, model version; a health endpoint |
| Out of scope | What you deliberately skip | Authentication, autoscaling, retraining |
Input validation rules for a model-serving endpoint
Models fail quietly. A scikit-learn model given columns in the wrong order will happily return a wrong answer. Validation is your main protection, so make it strict and explicit.
Validation layers, in the order they run
- Structure: the body is valid JSON and contains exactly the expected fields. Reject unknown fields rather than ignoring them, so typos surface early.
- Types: integers are integers, strings are strings. Do not silently convert
"abc"to a number. - Ranges and categories: numeric values inside the range seen in training; categorical values from a fixed list.
- Size limits: maximum text length, maximum rows per batch request, maximum body size.
- Feature assembly: build the feature row in the exact order stored in your metadata file, never in the order the caller happened to send it.
- Output check: confirm the model output is finite and inside the expected range before returning it.
In Python, Pydantic models (used natively by FastAPI) express layers one to four declaratively. Layers five and six are short functions you write and unit test yourself.
Validation test cases to write
- A valid request returns the expected shape.
- A missing required field returns 422 with the field name in the message.
- A value outside the allowed range returns 422.
- An unknown category returns 422, not a model error.
- An oversized batch is rejected before the model is called.
- Fields sent in a different order still produce the same prediction.
Loading the model once, and keeping the endpoint thin
The most common beginner mistake is loading the model file inside the request handler. This adds disk reads to every call and ruins your latency numbers. Load once at application startup and keep the object in memory.
Keep the layers separate so each can be tested alone:
- Schemas module: request and response definitions.
- Model module: loading, feature assembly and a
predictfunction with no web code. - API module: routes that validate, call
predictand shape the response. - Tests folder: unit tests for the model module, and API tests using the framework’s test client.
Add a /health endpoint that reports whether the model is loaded and which version, so a deployment tool or a reviewer can check readiness without sending a prediction.
Latency checks: set a budget, then measure it
Latency is not one number. A request passes through parsing, validation, feature assembly, inference and serialisation. Measure each stage so you know where time goes.
A simple measurement method
- Wrap the stages with a high-resolution timer such as
time.perf_counter()and log the durations with a request ID. - Run a warm-up of 20 to 50 requests and discard them, because the first calls are slower.
- Send at least 500 requests with a small script and record every duration.
- Report p50, p95 and the maximum, not the average alone. The average hides slow outliers.
- Repeat with concurrent callers (for example 10 at once) and report how the numbers change.
- Record your machine, Python version and library versions beside the results.
What usually dominates latency
- Model inference: grows with model size and, for text, input length.
- Preprocessing: tokenisation or encoding can cost more than the model itself.
- Blocking calls: running heavy CPU work directly in an async handler can stall other requests; consider a thread pool or a separate worker for it.
- Serialisation: large responses cost time to encode.
Your numbers are specific to your hardware. Present them as measured on your setup and never as general claims about the model or framework.
Batch versus real-time serving: trade-offs table
Decide the serving mode from the caller’s need, not from habit. The table compares the two approaches on the factors that matter in a small project.
| Factor | Real-time serving | Batch serving |
|---|---|---|
| Typical caller | A user-facing app waiting for an answer | A scheduled job or analyst processing many records |
| Latency expectation | Milliseconds to a second per request | Minutes or hours for the whole job |
| Throughput efficiency | Lower; one row at a time wastes vectorised speed | Higher; models process many rows together efficiently |
| Infrastructure | Always-on service that must stay healthy | Runs on demand, can use idle capacity |
| Failure handling | Caller sees errors immediately; needs clear status codes and timeouts | Can retry failed chunks; needs a record of what succeeded |
| Freshness | Uses the latest input and latest model instantly | Results can be stale until the next run |
| Validation approach | Reject the request on the first bad field | Often report bad rows separately and continue with good ones |
| Testing effort | Concurrency and timeout behaviour matter | Large-file handling and partial failure matter |
| Cost pattern | Pay for idle time | Pay only while running |
| Best fit for a 14-day project | One endpoint, strong validation and latency report | One endpoint or script that accepts a file or a list of rows |
A sensible compromise is a real-time endpoint for single predictions plus a capped batch endpoint. State the cap in your design note and enforce it in validation.
Worked illustration: a ticket-urgency service (illustrative)
This example is illustrative. It shows the reasoning, and no code or tests are claimed to have been run.
Suppose you have a logistic regression model with three features: ticket_length, channel and previous_tickets. Your design decisions might look like this:
- Schema:
ticket_lengthinteger from 1 to 5000,channelone of email, chat or phone,previous_ticketsinteger from 0 to 100. Extra fields are rejected. - Feature order: stored in
model_v1.meta.jsonand used by the assembly function, with channel one-hot encoded using the categories saved at training time. - Endpoints:
POST /predictfor one ticket,POST /predict/batchfor up to 100, andGET /health. - Budget: p95 under 100 ms for single requests on the development laptop.
- Measurement: after a 50-request warm-up, you send 500 requests and then repeat with 10 concurrent callers. Suppose the concurrent run shows a noticeably higher p95. You would investigate whether a blocking call is the cause and record both the finding and the fix.
- Failure behaviour: if the model file is missing at startup, the service starts but
/healthreports not ready and/predictreturns 503.
The write-up then states the measured figures, the machine used and what you would change with more time, such as caching repeated inputs or moving batch work to a background job.
A 14-day plan for the project
| Days | Focus | Output |
|---|---|---|
| 1-2 | Choose model and data; save artefact with metadata | model_v1.joblib and metadata file |
| 3 | Complete the design template | DESIGN.md draft |
| 4-5 | Schemas and the model module with predict |
Unit-tested prediction function |
| 6-7 | API routes, error contract, health endpoint | Working single-prediction service |
| 8 | Validation test suite | Tests for every case listed above |
| 9-10 | Stage timing, logging, load script | Latency log and first measurements |
| 11 | Batch endpoint with row cap | Batch route and tests |
| 12 | Concurrency run and one optimisation | Before and after numbers |
| 13 | README, run instructions, optional Dockerfile | Reproducible setup |
| 14 | Final design note and short demo | Submission-ready repository |
Self-review scorecard before you submit
| Criterion | Strong | Weak |
|---|---|---|
| Validation | Schema, ranges, categories and size limits all enforced and tested | Only type checks |
| Model handling | Loaded once; version reported in responses | Loaded inside each request |
| Latency evidence | p50 and p95 after warm-up, with environment noted | One timing taken once |
| Error behaviour | Distinct, documented status codes | Generic 500 for everything |
| Serving choice | Mode justified by caller need | No stated reason |
| Reproducibility | Pinned dependencies and two-step run | Works only on your machine |
| Honesty | Limits and untested areas written down | Claims without measurements |
Plaksha University students: fitting this project into your programme
Plaksha describes its undergraduate programme as starting with a compulsory three-semester “freshmore” foundation in mathematics, computing and data science, with students choosing a major at the end of semester three, according to the undergraduate programme page. The same page lists BTech degrees including Computer Science & Artificial Intelligence and Data Science, and a minor in Artificial Intelligence. In practice, that foundation gives you the Python, maths and data background this project assumes, so you can spend your two weeks on the service layer rather than on model theory.
The page also states that BTech students go on an eight-week summer internship after semester four, and that semester eight offers an industry internship, research or electives. A 14-day online project is shorter than either of those, so think of it as a portfolio piece you can complete alongside coursework or during a break, and one you can later extend. The page also mentions a project-based Innovation Lab and Grand Challenges studio across semesters 1 to 6; if your studio work involves a model, wrapping it in an API could be a natural extension.
Plaksha’s Office of Corporate Partnerships and Careers (CPC) is described on the same page as handling corporate partnerships and student career outcomes. Formal rules on internship credit, evaluation, documentation and whether online internships qualify were not confirmed, so do not assume this project counts toward any requirement until you have checked.
Verification steps for Plaksha students
- Email the CPC office and ask in writing whether a short online internship can be listed on your record, and what documents they would want.
- Ask your faculty advisor whether it can count toward, or must stay separate from, the eight-week summer internship requirement.
- Request the current internship guidelines or handbook for your batch and read the sections on credit and evaluation.
- Open the Placements page to see what career information the university publishes, and treat any figures there as the official source.
- Check with your course instructors whether any dataset or model from coursework has usage limits before you publish it in a public repository.
Documenting trade-offs in your final design note
Close the project with a one-page note. Reviewers value the reasoning as much as the code. Include:
- The final input and output schemas and why you chose those limits.
- The measured latency table with machine details.
- The serving mode you chose and the alternative you rejected.
- Two failure scenarios you handled and one you did not.
- Next steps: authentication, a model registry, monitoring for input drift and a retraining trigger.
Frequently Asked Questions
Which Python framework should I use for a model-serving API?
FastAPI is a common choice because Pydantic validation and automatic documentation come built in, which suits this project. Flask works too, but you would add validation yourself. Pick one and spend your time on the design rather than comparing frameworks.
Do I need to train the model myself?
No. A model trained in a course exercise or a simple scikit-learn pipeline is enough. The project is judged on the service around it, so keep the model small and well documented.
How many requests are enough to measure latency fairly?
Use a warm-up of a few dozen requests, then at least a few hundred measured ones so p95 is meaningful. Repeat under concurrent load and record your hardware, since results differ between machines.
Should I choose batch or real-time serving?
Choose according to who calls the service. If a person or app waits for the answer, use real-time. If records are processed in bulk on a schedule, use batch. A capped batch endpoint beside a single-prediction endpoint is a reasonable middle path.
Is Docker required?
It is optional but helpful for reproducibility. If time is short, pinned dependencies and clear run commands in the README matter more than a perfect container.
What should I do if the model gives a confident but wrong answer on unusual input?
Validate against training ranges, reject out-of-range values and consider returning a warning field for inputs near the edge. Document that a validated request is still not a guaranteed correct prediction.
Will this project earn academic credit at my university?
The CareerSwami internship is free, runs for two weeks and provides an offer letter and a completion certificate after successful completion. It does not promise credit. Ask your university in writing whether any short internship can count.
How should I present the project to a recruiter or faculty member?
Share the repository link, the design note and the latency table. Lead with the problem the service solves and the decisions you made, and be clear about what is out of scope.
Ready to put this into practice?
Join the free two-week CareerSwami online internship in Python & Backend Engineering. The internship, the offer letter and the completion certificate are free.




