PyTorch Model to CLI Tool Conversion
This skill provides guidance for tasks that require converting PyTorch models into standalone command-line tools, typically implemented in C/C++ for portability and independence from Python runtime.
Task Recognition
This skill applies when the task involves:
- Converting a PyTorch model to a standalone executable
- Extracting model weights to a portable format (JSON, binary)
- Implementing neural network inference in C/C++
- Creating CLI tools that perform image classification or prediction
- Building inference tools using libraries like cJSON and lodepng
Recommended Approach
Phase 1: Environment Analysis
Before writing any code, thoroughly analyze the available resources:
Identify the model architecture
- Read the model definition file (e.g.,
model.py) completely
- Document all layer types, dimensions, and activation functions
- Note any default parameters (hidden dimensions, number of classes)
Examine available libraries
- Check for image loading libraries (lodepng, stb_image)
- Check for JSON parsing libraries (cJSON, nlohmann/json)
- Identify compilation requirements (headers, source files)
Understand input requirements
- Determine expected image dimensions (e.g., 28x28 for MNIST)
- Identify color format (grayscale, RGB, RGBA)
- Document normalization requirements (divide by 255, mean/std normalization)
Verify preprocessing pipeline
- If training code is available, examine data transformations
- Match inference preprocessing exactly to training preprocessing
- Common transformations: resize, grayscale conversion, normalization
Phase 2: Weight Extraction
Extract model weights from PyTorch format to a portable format:
Load the model checkpoint
import torch
import json
# Load state dict
state_dict = torch.load('model.pth', map_location='cpu')
Convert tensors to lists
weights = {}
for key, tensor in state_dict.items():
weights[key] = tensor.numpy().tolist()
Save to JSON
with open('weights.json', 'w') as f:
json.dump(weights, f)
Verify extraction
- Check that all expected layer weights are present
- Verify dimensions match the model architecture
- For a model with layers fc1, fc2, fc3: expect fc1.weight, fc1.bias, etc.
Phase 3: Reference Implementation
Before implementing in C/C++, create a reference output:
Run inference in PyTorch
model.eval()
with torch.no_grad():
output = model(input_tensor)
prediction = output.argmax().item()
Save reference outputs
- Store intermediate layer outputs for debugging
- Record the final prediction for verification
- This allows validating the C/C++ implementation
Phase 4: C/C++ Implementation
Implement the inference logic in C/C++:
Image loading and preprocessing
- Load image using the available library (lodepng for PNG)
- Handle color channel conversion (RGBA to grayscale if needed)
- Apply normalization (typically divide by 255.0)
- Flatten to 1D array in correct order (row-major)
Weight loading
- Parse JSON file containing weights
- Store weights in appropriate data structures
- Verify dimensions during loading
Forward pass implementation
- Implement matrix-vector multiplication for linear layers
- Implement activation functions (ReLU, softmax, etc.)
- Process layers in correct order
Output handling
- Find argmax for classification tasks
- Write prediction to output file
- Ensure only prediction goes to stdout (not progress/debug info)
Phase 5: Compilation and Testing
Compile with appropriate flags
g++ -o cli_tool main.cpp lodepng.cpp cJSON.c -std=c++11 -lm
- Double-check flag syntax (avoid concatenation errors like
-std=c++11-lm)
Test against reference
- Run the CLI tool on the same input used for reference
- Compare output to PyTorch reference
- Debug any discrepancies by checking intermediate values
Verification Strategies
Before Implementation
After Weight Extraction
After C/C++ Implementation
Final Validation
Common Pitfalls
Weight Extraction
- Forgetting to use
map_location='cpu' when loading on CPU-only systems
- Missing bias terms - ensure both weights and biases are extracted
- Incorrect tensor ordering - PyTorch uses different conventions than some C libraries
Preprocessing Mismatches
- Wrong normalization - training might use mean/std normalization, not just /255
- Color channel issues - PNG might be RGBA while model expects grayscale
- Dimension ordering - ensure row-major vs column-major consistency
C/C++ Implementation
- Matrix multiplication order - verify (input × weights^T) vs (weights × input)
- Activation function placement - apply after linear layer, before next layer
- Integer vs float division - use 255.0, not 255, for normalization
Compilation Issues
- Flag concatenation - ensure spaces between compiler flags
- Missing libraries - include all required source files (lodepng.cpp, cJSON.c)
- Header dependencies - verify all headers are in include path
Output Handling
- Verbose library output - suppress or redirect debug/progress output
- Newline handling - ensure consistent line endings in output files
- Buffering issues - flush stdout before program exit
Efficiency Guidelines
- Avoid repeatedly checking package managers; identify available tools first
- Create reference outputs early to catch implementation bugs quickly
- Review complete code before compilation attempts
- Minimize status-only updates; batch related operations
- Test with multiple inputs when possible, not just the provided test case
1---2name: pytorch-model-cli3description: Guidance for creating standalone CLI tools that perform neural network inference by extracting PyTorch model weights and reimplementing inference in C/C++. This skill applies when tasks involve converting PyTorch models to standalone executables, extracting model weights to portable formats (JSON), implementing neural network forward passes in C/C++, or creating CLI tools that load images and run inference without Python dependencies.4---56# PyTorch Model to CLI Tool Conversion78This skill provides guidance for tasks that require converting PyTorch models into standalone command-line tools, typically implemented in C/C++ for portability and independence from Python runtime.910## Task Recognition1112This skill applies when the task involves:13- Converting a PyTorch model to a standalone executable14- Extracting model weights to a portable format (JSON, binary)15- Implementing neural network inference in C/C++16- Creating CLI tools that perform image classification or prediction17- Building inference tools using libraries like cJSON and lodepng1819## Recommended Approach2021### Phase 1: Environment Analysis2223Before writing any code, thoroughly analyze the available resources:24251. **Identify the model architecture**26 - Read the model definition file (e.g., `model.py`) completely27 - Document all layer types, dimensions, and activation functions28 - Note any default parameters (hidden dimensions, number of classes)29302. **Examine available libraries**31 - Check for image loading libraries (lodepng, stb_image)32 - Check for JSON parsing libraries (cJSON, nlohmann/json)33 - Identify compilation requirements (headers, source files)34353. **Understand input requirements**36 - Determine expected image dimensions (e.g., 28x28 for MNIST)37 - Identify color format (grayscale, RGB, RGBA)38 - Document normalization requirements (divide by 255, mean/std normalization)39404. **Verify preprocessing pipeline**41 - If training code is available, examine data transformations42 - Match inference preprocessing exactly to training preprocessing43 - Common transformations: resize, grayscale conversion, normalization4445### Phase 2: Weight Extraction4647Extract model weights from PyTorch format to a portable format:48491. **Load the model checkpoint**50 ```python51 import torch52 import json5354 # Load state dict55 state_dict = torch.load('model.pth', map_location='cpu')56 ```57582. **Convert tensors to lists**59 ```python60 weights = {}61 for key, tensor in state_dict.items():62 weights[key] = tensor.numpy().tolist()63 ```64653. **Save to JSON**66 ```python67 with open('weights.json', 'w') as f:68 json.dump(weights, f)69 ```70714. **Verify extraction**72 - Check that all expected layer weights are present73 - Verify dimensions match the model architecture74 - For a model with layers fc1, fc2, fc3: expect fc1.weight, fc1.bias, etc.7576### Phase 3: Reference Implementation7778Before implementing in C/C++, create a reference output:79801. **Run inference in PyTorch**81 ```python82 model.eval()83 with torch.no_grad():84 output = model(input_tensor)85 prediction = output.argmax().item()86 ```87882. **Save reference outputs**89 - Store intermediate layer outputs for debugging90 - Record the final prediction for verification91 - This allows validating the C/C++ implementation9293### Phase 4: C/C++ Implementation9495Implement the inference logic in C/C++:96971. **Image loading and preprocessing**98 - Load image using the available library (lodepng for PNG)99 - Handle color channel conversion (RGBA to grayscale if needed)100 - Apply normalization (typically divide by 255.0)101 - Flatten to 1D array in correct order (row-major)1021032. **Weight loading**104 - Parse JSON file containing weights105 - Store weights in appropriate data structures106 - Verify dimensions during loading1071083. **Forward pass implementation**109 - Implement matrix-vector multiplication for linear layers110 - Implement activation functions (ReLU, softmax, etc.)111 - Process layers in correct order1121134. **Output handling**114 - Find argmax for classification tasks115 - Write prediction to output file116 - Ensure only prediction goes to stdout (not progress/debug info)117118### Phase 5: Compilation and Testing1191201. **Compile with appropriate flags**121 ```bash122 g++ -o cli_tool main.cpp lodepng.cpp cJSON.c -std=c++11 -lm123 ```124 - Double-check flag syntax (avoid concatenation errors like `-std=c++11-lm`)1251262. **Test against reference**127 - Run the CLI tool on the same input used for reference128 - Compare output to PyTorch reference129 - Debug any discrepancies by checking intermediate values130131## Verification Strategies132133### Before Implementation134- [ ] Model architecture fully documented135- [ ] All layer dimensions verified136- [ ] Preprocessing requirements identified137- [ ] Reference output generated from PyTorch138139### After Weight Extraction140- [ ] All expected keys present in JSON141- [ ] Weight dimensions match architecture142- [ ] Bias terms included for all layers143144### After C/C++ Implementation145- [ ] Compilation succeeds without warnings146- [ ] Output matches PyTorch reference exactly147- [ ] CLI tool handles missing files gracefully148- [ ] Only prediction output goes to stdout149150### Final Validation151- [ ] All test cases pass152- [ ] Memory properly managed (no leaks)153- [ ] Error messages go to stderr, not stdout154155## Common Pitfalls156157### Weight Extraction158- **Forgetting to use `map_location='cpu'`** when loading on CPU-only systems159- **Missing bias terms** - ensure both weights and biases are extracted160- **Incorrect tensor ordering** - PyTorch uses different conventions than some C libraries161162### Preprocessing Mismatches163- **Wrong normalization** - training might use mean/std normalization, not just /255164- **Color channel issues** - PNG might be RGBA while model expects grayscale165- **Dimension ordering** - ensure row-major vs column-major consistency166167### C/C++ Implementation168- **Matrix multiplication order** - verify (input × weights^T) vs (weights × input)169- **Activation function placement** - apply after linear layer, before next layer170- **Integer vs float division** - use 255.0, not 255, for normalization171172### Compilation Issues173- **Flag concatenation** - ensure spaces between compiler flags174- **Missing libraries** - include all required source files (lodepng.cpp, cJSON.c)175- **Header dependencies** - verify all headers are in include path176177### Output Handling178- **Verbose library output** - suppress or redirect debug/progress output179- **Newline handling** - ensure consistent line endings in output files180- **Buffering issues** - flush stdout before program exit181182## Efficiency Guidelines183184- Avoid repeatedly checking package managers; identify available tools first185- Create reference outputs early to catch implementation bugs quickly186- Review complete code before compilation attempts187- Minimize status-only updates; batch related operations188- Test with multiple inputs when possible, not just the provided test case