AI Development Framework · Topic 2 of 2
PyTorch and AI Application Development
Learn PyTorch nn.Module, losses, optimizers, DataLoader, the training loop, evaluation and saving, and the AI application development process for H13-311.
- 5 min
- Models inherit from
nn.Module; layers go in__init__, computation inforward(). - Training order per batch:
zero_grad(), forward pass, loss,backward(),step(). DataLoaderbatches and shuffles aDataset; one pass over all data is an epoch.
What it is
PyTorch is an open source deep learning framework in Python, created by Meta and now hosted by the PyTorch Foundation. It uses dynamic computational graphs and is the framework used throughout the HCIA-AI V4.0 course.
The AI application development process is the sequence of steps that turns a business need into a working model: define the problem, prepare data, build and train a model, evaluate it, deploy it and keep improving it.
How it works
Main PyTorch modules
| Module | Role | Common items |
|---|---|---|
torch | Tensors and math | torch.tensor, torch.randn, torch.matmul |
torch.autograd | Automatic differentiation | requires_grad, backward() |
torch.nn | Layers, activations, losses | nn.Module, nn.Linear, nn.Conv2d, nn.ReLU, nn.CrossEntropyLoss |
torch.optim | Optimizers | optim.SGD, optim.Adam |
torch.utils.data | Data loading | Dataset, DataLoader |
Every model is a class that inherits from nn.Module. Layers are created in __init__, and the computation is written in forward(). You normally do not call forward() directly; you call the model, model(x), which also runs any registered hooks.
A complete training loop
This network classifies 28 x 28 handwritten digits (flattened to 784 values) into 10 classes.
import torch
from torch import nn
from torch.utils.data import DataLoader
class Net(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(784, 128)
self.fc2 = nn.Linear(128, 10)
def forward(self, x):
return self.fc2(torch.relu(self.fc1(x)))
model = Net()
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
loader = DataLoader(train_set, batch_size=64, shuffle=True)
model.train()
for images, labels in loader:
optimizer.zero_grad() # clear old gradients
loss = loss_fn(model(images.view(-1, 784)), labels)
loss.backward() # compute gradients
optimizer.step() # update weights
train_set is any Dataset; the DataLoader splits it into shuffled batches of 64. One full pass over the data is an epoch, and real training repeats this loop for several epochs.
Why the order matters
PyTorch accumulates gradients: each backward() adds to the existing .grad values. If you skip optimizer.zero_grad(), the gradients of earlier batches pile up and the updates are wrong.
backward() must come before step(), because the optimizer needs gradients to update the weights.
Evaluation, devices and saving
| Task | Code | Why |
|---|---|---|
| Switch to evaluation | model.eval() | Dropout is turned off and batch normalization uses its stored statistics |
| Stop gradient tracking | with torch.no_grad(): | Saves memory and time during inference |
| Use a GPU | model.to("cuda") and x.to("cuda") | Model and data must be on the same device |
| Save weights | torch.save(model.state_dict(), "model.pth") | Stores the learned parameters |
| Load weights | model.load_state_dict(torch.load("model.pth")) | Restores them into a model of the same structure |
model.eval()
with torch.no_grad():
preds = model(test_images.view(-1, 784)).argmax(dim=1)
On Huawei Ascend NPUs, PyTorch runs through the torch_npu adapter (Ascend Extension for PyTorch), so the same training code can target Ascend hardware.
The AI application development process
| Step | What happens |
|---|---|
| Requirement analysis | Define the business problem, the task type (classification, regression, detection) and the success metric |
| Data preparation | Collect, clean and label data; split it into training, validation and test sets |
| Model building | Choose or design an architecture, or start from a pretrained model |
| Training | Run the training loop and tune hyperparameters such as learning rate and batch size on the validation set |
| Evaluation | Measure the model on the untouched test set with metrics such as accuracy, precision and recall |
| Deployment | Serve the model in the cloud, at the edge or on a device, often after export or compression |
| Monitoring and iteration | Watch real performance, collect new data and retrain when accuracy drops |
The process is a loop, not a straight line. Poor evaluation results send you back to the data or the model.
A worked example
Count the trainable parameters of Net above. An nn.Linear(in, out) layer has in x out weights plus out biases.
- fc1: 784 x 128 + 128 = 100,352 + 128 = 100,480
- fc2: 128 x 10 + 10 = 1,280 + 10 = 1,290
- Total: 100,480 + 1,290 = 101,770
PyTorch confirms it with sum(p.numel() for p in model.parameters()).
How the exam asks about this
- "Which base class must a custom PyTorch model inherit from?" →
torch.nn.Module. - "Which call clears the gradients left by the previous batch?" →
optimizer.zero_grad(). - "Which dataset is used for the final, unbiased estimate of model performance?" → The test set.
What to remember for the exam
- Models inherit from
nn.Module; layers go in__init__, computation inforward(). - Training order per batch:
zero_grad(), forward pass, loss,backward(),step(). DataLoaderbatches and shuffles aDataset; one pass over all data is an epoch.- For inference use
model.eval()andtorch.no_grad(). - Process: requirements, data, model, training, evaluation, deployment, monitoring and iteration.
nn.CrossEntropyLoss expects raw scores (logits) and applies log softmax internally. Adding your own softmax layer before it is a classic bug: the loss is computed on doubly normalized scores and training suffers.
Common mistakes
Thinking model.eval() stops gradient computation. It only changes the behavior of layers such as dropout and batch normalization. Gradient tracking is turned off with torch.no_grad() (or torch.inference_mode()).
Tuning on the test set. Hyperparameters are chosen with the validation set. If the test set guides your choices, its score is no longer an honest estimate.
Treating deployment as the last step. Data in production changes over time. Models must be monitored and retrained, so the process loops back to data preparation.
Check yourself
What happens if
optimizer.zero_grad()is never called?Gradients accumulate across batches, because
backward()adds to existing gradients, so each update uses the wrong values.How many parameters does
nn.Linear(100, 10)have?1,010: 100 x 10 = 1,000 weights plus 10 biases.
Why is the validation set separate from the test set?
The validation set is used to tune hyperparameters and choose models, while the test set is kept untouched for the final unbiased performance estimate.
Topic 2 of 2 in AI Development Framework
Test yourself on AI Development Framework
The full Huawei HCIA-AI H13-311 question bank has 600 questions, with timed practice exams and an explanation for every answer.
This study guide is independent and is not affiliated with, endorsed by, or sponsored by Huawei. Vendor names, certification names and exam codes are trademarks of their respective owners and are used for identification only.