We welcome contributions to the NeMo Evaluator projects! This document provides guidelines for contributing to both the nemo-evaluator core framework and nemo-evaluator-launcher orchestration tool.
- Python 3.10 or higher (up to 3.13)
- UV for fast Python package management
- Git for version control
This is a monorepo containing two packages:
packages/nemo-evaluator- Core evaluation library (required for building docs)packages/nemo-evaluator-launcher- CLI and orchestration layer
Each package has its own virtual environment managed by UV. Choose your setup based on what you're contributing to.
-
Install UV
curl -LsSf https://astral.sh/uv/install.sh | sh -
Clone the repository
git clone <repository-url> cd Evaluator
-
Set up development environment
Choose the setup that matches your contribution:
For Launcher Development:
cd packages/nemo-evaluator-launcher uv sync --all-extras uv run pre-commit installFor Core Library Development:
cd packages/nemo-evaluator uv sync --all-extras uv run pre-commit installFor Documentation:
# 1. First, sync the documentation dependencies make docs-env # 2. Build the HTML documentation make docs-html # 3. View the built documentation python3 -m http.server --directory docs/_build/html 8000
Then open your browser to: http://localhost:8000
If you want to see changes in real-time as you edit run the command below:
# This starts a live-reload server that automatically rebuilds on changes make docs-liveThis will start a server at http://localhost:8000 that automatically rebuilds when you save changes to any documentation files.
The project uses the following tools for development:
- UV: Fast Python package installer and resolver
- Ruff: Code formatting and linting
- MyPy: Static type checking
- pytest: Testing framework
- pre-commit: Git hooks for code quality
We use Ruff for consistent code formatting and linting:
# Format code manually
uv run ruff format .
uv run ruff check . --fix
# Or run pre-commit to format and check everything
uv run pre-commit run --all-filesWe enforce strict type checking with MyPy. All public functions and methods must have type annotations.
- Follow Python conventions: Use PEP 8 style guidelines (enforced by the linting tool above)
- Type annotations: All public APIs must have complete type annotations
- Documentation: Add docstrings for all public classes and methods
- Error handling: Use explicit error handling with appropriate exception types
- Testing: Write tests for new functionality and bug fixes
- Logging: Use structured logging via
structloginstead of print statements
# Run all tests
uv run pytest
# Run tests with coverage
uv run pytest --cov=src --cov-report=term-missing
# Run specific test file
uv run pytest tests/test_specific_module.py
# Run tests without network access (default)
uv run pytest --disable-network- Unit tests are located in the
tests/directory - Test files should follow the naming pattern
test_*.py - Use descriptive test names that explain what is being tested
- Group related tests in classes when appropriate
- Mock external dependencies and network calls
- Test coverage: Aim for high test coverage, especially for core functionality
- Test isolation: Each test should be independent and not rely on others
- Clear assertions: Use descriptive assertion messages
- Mock external dependencies: Use
pytestfixtures and mocking for external services
Documentation builds without executing code snippets, but you may want to validate that snippets are syntactically correct and have valid imports.
To validate snippets that import from both packages:
# Set up launcher environment with core library
cd packages/nemo-evaluator-launcher
uv sync --all-extras
uv pip install -e ../nemo-evaluator/
# Activate environment and validate a snippet
source .venv/bin/activate
python -m py_compile docs/evaluation/_snippets/api-examples/basic_evaluate.pyNote: Most snippets require actual model endpoints to run, so validation only checks syntax and imports, not execution.
-
Create an issue: For significant changes, create an issue first to discuss the approach
-
Branch naming: Use descriptive branch names (e.g.,
feature/add-new-exporter,fix/memory-leak) -
Code quality: Ensure all checks pass:
uv run pre-commit run --all-files uv run pytest
- Clear description: Explain what the PR does and why
- Tests: Include tests for new functionality or bug fixes
- Documentation: Update documentation if needed
- Type safety: Ensure MyPy passes without errors
- Backwards compatibility: Avoid breaking changes unless necessary
- Fork the repository: External contributors should fork the repository to their GitHub account
- Clone and branch: Clone your fork and create a feature branch from
main - Make changes: Implement your changes with tests
- Test thoroughly: Run the full test suite
- Push to fork: Push your branch to your forked repository
- Submit PR: Create a pull request from your fork's branch to the main repository
- Address feedback: Respond to review comments
- Squash commits: Clean up commit history before merging
To add a new execution backend:
- Create a new module in
src/nemo_evaluator_launcher/executors/ - Implement the
BaseExecutorinterface - Register the executor in the registry
- Add configuration schema
- Write comprehensive tests
- Update documentation
To add a new result exporter:
- Create a new module in
src/nemo_evaluator_launcher/exporters/ - Implement the
BaseExporterinterface - Register the exporter in the registry
- Add optional dependencies to
pyproject.toml - Write tests with mocked external services
- Update documentation
To add new CLI commands:
- Create a new module in the appropriate
cli/directory - Use
simple-parsingfor argument parsing - Follow existing patterns for error handling and logging
- Add tests for the CLI interface
- Update help documentation
<type>(<scope>): <description>
[optional body]
[optional footer(s)]
Types:
feat: New featuresfix: Bug fixesdocs: Documentation changesstyle: Code style changes (formatting, etc.)refactor: Code refactoringtest: Adding or updating testschore: Maintenance tasks
Examples:
feat(exporters): add S3 exporter support
feat(tasks): add new MMLU evaluation task
fix(cli): handle missing configuration files gracefully
fix(evaluation): resolve memory leak in batch processing
docs: update installation instructions
test(executors): add tests for Slurm executor- Documentation: Check the README and inline documentation
- Issues: Search existing issues before creating new ones
- Discussions: Use GitHub discussions for questions
- Code Review: Ask for help in pull request comments
- Issues: Use GitHub issues for bug reports and feature requests
- Discussions: Use GitHub discussions for questions and general discussion
- Pull Requests: Use PRs for code contributions with clear descriptions
-
We require that all contributors "sign-off" on their commits. This certifies that the contribution is your original work, or you have rights to submit it under the same license, or a compatible license.
- Any contribution which contains commits that are not Signed-Off will not be accepted.
-
To sign off on a commit you simply use the
--signoff(or-s) option when committing your changes:git commit -s -m "Add cool feature."This will append the following to your commit message:
Signed-off-by: Your Name <your@email.com> -
Full text of the DCO:
Developer Certificate of Origin Version 1.1 Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 1 Letterman Drive Suite D4700 San Francisco, CA, 94129 Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.Developer's Certificate of Origin 1.1 By making a contribution to this project, I certify that: (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved.
There are two ways to trigger CI tests on your pull request:
If your GitHub user is configured to use signed commits, CI tests will run automatically when you push commits to your pull request.
Note: Signed commits are different from signing-off on commits (which uses the
-sflag mentioned in the Signing Your Work section).
If you don't have signed commits set up, you can still trigger CI tests manually by commenting on your pull request:
/ok to test <commit-SHA>
For example:
/ok to test a1b2c3d4e5f6
Important: You'll need to add this comment for each new commit you push to ensure CI tests run on the latest changes.
You can find the commit SHA in several ways:
- View your pull request's commit history on GitHub
- Run
git log --oneline -1in your local repository - Check the commit details in your Git client