Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/links.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Links
# The course is mostly links to other people's work, and those rot silently: nothing in
# push CI notices when a referenced article disappears. This is the counterpart — slow,
# network-bound, and scheduled, so a dead link is found by a job nobody is waiting on
# rather than by a reader.
on:
schedule:
- cron: "23 4 1 * *"
workflow_dispatch:
permissions:
contents: read
concurrency:
group: links
cancel-in-progress: true
jobs:
check:
name: External link check
runs-on: ubuntu-24.04
timeout-minutes: 20
steps:
- name: Checkout repository
uses: actions/checkout@v7
with:
persist-credentials: false # the checker only reads the checkout
- name: Install mise toolchain
uses: jdx/mise-action@v4
with:
cache: true
- name: Check external links
run: mise run check:links
14 changes: 14 additions & 0 deletions .lycheeignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Hosts that answer a link checker with 403 or 429 rather than the page a reader gets.
# These are not broken links: they are anti-bot measures and rate limits. Keeping them
# out means a finding in `mise run check:links` is worth acting on.
https://medium\.com/.*
https://.*\.medium\.com/.*
https://.*\.readthedocs\.io/.*
https://www\.reddit\.com/.*
https://neptune\.ai/.*
https://twitter\.com/.*
https://x\.com/.*
https://www\.linkedin\.com/.*
# Illustrative URLs in the prose, not references to anything on the internet.
https?://localhost.*
https?://127\.0\.0\.1.*
2 changes: 1 addition & 1 deletion docs/1. Initializing/1.6. VS Code.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ To accelerate your learning curve, explore these excellent resources:

- **[Official Documentation](https://code.visualstudio.com/docs)**: The definitive source for every feature.
- **[VS Code Tips and Tricks](https://code.visualstudio.com/docs/getstarted/tips-and-tricks)**: A collection of shortcuts and best practices to boost your productivity.
- **[Microsoft Learn](https://docs.microsoft.com/en-us/learn/modules/use-vscode/)**: Free, hands-on tutorials for various development scenarios.
- **[Microsoft Learn](https://learn.microsoft.com/en-us/training/browse/?products=vs-code)**: Free, hands-on tutorials for various development scenarios.
- **[Official YouTube Channel](https://www.youtube.com/@code)**: Visual guides and tutorials for all skill levels.

## Which extensions are essential for MLOps?
Expand Down
2 changes: 1 addition & 1 deletion docs/2. Prototyping/2.0. Notebooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ Saving notebook outputs in your Git repository is generally not recommended due
- **Collaboration**: Sharing outputs can lead to conflicts and confusion when multiple users work on the same notebook, as the outputs may not match the code execution.
- **Code Focus**: The primary focus of version control systems like Git is on tracking changes to code, not data or outputs. Including outputs can distract from the main purpose of the repository.

Instead of saving outputs directly in the repository, consider using tools like [Jupyter's nbconvert](https://nbconvert.readthedocs.io/en/latest/) to export notebooks to different formats (e.g., HTML, PDF) that can be shared on other platforms or included in documentation. You can also use [Jupyter's built-in cell tags](https://jupyterbook.org/interactive/hiding.html) to hide or exclude specific cells from the exported version, allowing you to control what information is shared while keeping the repository clean and focused on code.
Instead of saving outputs directly in the repository, consider using tools like [Jupyter's nbconvert](https://nbconvert.readthedocs.io/en/latest/) to export notebooks to different formats (e.g., HTML, PDF) that can be shared on other platforms or included in documentation. You can also use [Jupyter's built-in cell tags](https://jupyterbook.org/en/stable/interactive/hiding.html) to hide or exclude specific cells from the exported version, allowing you to control what information is shared while keeping the repository clean and focused on code.

## Additional Resources

Expand Down
2 changes: 1 addition & 1 deletion docs/2. Prototyping/2.5. Modeling.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ description: Learn how to build, refine, and compare machine learning models dir
[Pipelines in machine learning](https://scikit-learn.org/stable/modules/compose.html#pipeline) provide a streamlined way to organize sequences of data preprocessing and modeling steps. They encapsulate a series of data transformations followed by the application of a model, facilitating both simplicity and efficiency in the development process. Pipelines can be broadly categorized as follows:

- **Model Pipeline**: Focuses specifically on sequences related to preparing data for machine learning models and applying these models. For instance, scikit-learn's [`Pipeline`](https://scikit-learn.org/stable/modules/compose.html#pipeline) class allows for chaining [preprocessors](https://scikit-learn.org/stable/modules/preprocessing.html) and [estimators](https://scikit-learn.org/stable/developers/develop.html).
- **Data Pipeline**: Encompasses a wider scope, including steps for data gathering, cleaning, and transformation. Tools such as [Prefect](https://www.prefect.io/) and [ZenML](https://docs.zenml.io/user-guide/starter-guide/create-an-ml-pipeline) offer capabilities for building comprehensive data pipelines.
- **Data Pipeline**: Encompasses a wider scope, including steps for data gathering, cleaning, and transformation. Tools such as [Prefect](https://www.prefect.io/) and [ZenML](https://docs.zenml.io/user-guides/starter-guide/create-an-ml-pipeline) offer capabilities for building comprehensive data pipelines.
- **Orchestration Pipeline**: Targets the automation of a series of tasks, including data and model pipelines, ensuring they execute in an orderly fashion or under specific conditions. Examples include [Apache Airflow](https://airflow.apache.org/) for creating directed acyclic graphs (DAGs) and [Vertex AI for managing ML workflows](https://cloud.google.com/vertex-ai/docs/pipelines/introduction).

For the purposes of this discussion, we'll focus on **model pipelines**, crucial for efficiently prototyping machine learning solutions. The code example are based on [scikit-learn pipeline](https://scikit-learn.org/stable/modules/generated/sklearn.pipeline.Pipeline.html), as this toolkit is simple to understand and its concept can be generalized to other types of pipeline like [Dagster](https://dagster.io/), [Prefect](https://www.prefect.io/), or [Metaflow](https://metaflow.org/).
Expand Down
2 changes: 1 addition & 1 deletion docs/3. Productionizing/3.2. Paradigms.md
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ Therefore, the most effective approach is to build an object-oriented foundation

## What is the hybrid OOP and functional style?

A [hybrid style](https://mlops.community/finding-harmony-in-mlops-balancing-functional-and-object-oriented-approaches-%E2%98%AF/) strategically combines OOP's structure with FP's discipline to create clean, robust, and maintainable code. It involves using objects as the primary architectural component but applying functional principles to their design.
A [hybrid style](https://mlops.community/blog/finding-harmony-in-mlops-balancing-functional-and-object-oriented-approaches) strategically combines OOP's structure with FP's discipline to create clean, robust, and maintainable code. It involves using objects as the primary architectural component but applying functional principles to their design.

Key principles of the hybrid style include:

Expand Down
2 changes: 1 addition & 1 deletion docs/3. Productionizing/3.6. VS Code Workspace.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ For team projects, it's best to use **Workspace Settings** to ensure everyone sh

## How can you optimize your VS Code User Settings for productivity?

While workspace settings standardize team environments, your personal user settings can significantly boost your individual productivity. This article from the MLOps Community provides an in-depth guide: [How to configure VS Code for AI, ML and MLOps development in Python 🛠️️](https://mlops.community/how-to-configure-vs-code-for-ai-ml-and-mlops-development-in-python-%f0%9f%9b%a0%ef%b8%8f%ef%b8%8f/).
While workspace settings standardize team environments, your personal user settings can significantly boost your individual productivity. This article from the MLOps Community provides an in-depth guide: [How to configure VS Code for AI, ML and MLOps development in Python 🛠️️](https://mlops.community/blog/how-to-configure-vs-code-for-ai-ml-and-mlops-development-in-python).

Key takeaways include:
- **Essential Extensions**: Beyond project recommendations, consider tools like GitLens (for Git history), Docker, and Thunder Client (for API testing).
Expand Down
2 changes: 1 addition & 1 deletion docs/6. Sharing/6.1. License.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ For a guided experience, use tools like [ChooseALicense.com](https://choosealice
Yes, licensing in AI/ML is more complex because you're often dealing with three distinct components: the **code**, the **model artifacts** (the trained weights), and the **data**. Each may require its own license.

- **Licensing the Code**: Standard software licenses like MIT or Apache 2.0 work perfectly well for the source code that trains or runs your model.
- **Licensing the Model**: This is an emerging area. You must decide if you are licensing the *use* of the model. Can others use it commercially? Can they build upon it? Specialized licenses like [OpenRAIL](https://www.licenses.ai/blog/2022/8/18/bigscience-open-rail-m-license) (Responsible AI Licenses) are designed to restrict the use of models in certain sensitive or unethical applications.
- **Licensing the Model**: This is an emerging area. You must decide if you are licensing the *use* of the model. Can others use it commercially? Can they build upon it? Specialized licenses like [OpenRAIL](https://huggingface.co/blog/open_rail) (Responsible AI Licenses) are designed to restrict the use of models in certain sensitive or unethical applications.
- **Licensing the Data**: Data licensing is critical. You must ensure you have the right to use the training data and clearly state how it can be used by others. [Creative Commons](https://creativecommons.org/) licenses are a popular standard for datasets, allowing you to specify whether commercial use is allowed or if derivatives must be shared.

## How do you manage licenses for your dependencies?
Expand Down
2 changes: 1 addition & 1 deletion docs/6. Sharing/6.5. Workstations.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ By committing this file to your repository, you ensure that anyone who opens the

Cloud workstations act as a centralized hub for development, making collaboration seamless:

- **Real-Time Co-Editing**: Tools like [Visual Studio Code Live Share](https://code.visualstudio.com/learn/collaboration/live-share) are natively integrated, allowing multiple developers to edit, debug, and run code in the same session simultaneously.
- **Real-Time Co-Editing**: Tools like [Visual Studio Code Live Share](https://visualstudio.microsoft.com/services/live-share/) are natively integrated, allowing multiple developers to edit, debug, and run code in the same session simultaneously.
- **Shared Terminals**: You can share a terminal session, which is invaluable for collaborative debugging or walking a teammate through a complex command-line workflow.
- **Consistent Environment**: Because everyone is working in an identical, containerized environment, you eliminate time wasted debugging environment-specific discrepancies. If the code runs in one developer's workstation, it will run in everyone's.

Expand Down
2 changes: 1 addition & 1 deletion docs/7. Observability/7.1. Monitoring.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,5 +159,5 @@ This process creates a detailed report that helps you quickly diagnose if and ho
- **[Example from the MLOps Python Package](https://github.com/fmind/mlops-python-package/blob/main/src/bikes/jobs/evaluations.py)**
- **[MLflow Evaluate API](https://mlflow.org/docs/latest/model-evaluation/index.html)**
- **[EvidentlyAI](https://www.evidentlyai.com/)**
- [Is AI/ML Monitoring just Data Engineering? 🤔](https://mlops.community/is-ai-ml-monitoring-just-data-engineering-%F0%9F%A4%94/)
- [Is AI/ML Monitoring just Data Engineering? 🤔](https://mlops.community/blog/is-ai-ml-monitoring-just-data-engineering)
- [Model Monitoring: What it is and why it's so hard](https://christophergs.com/machine%20learning/2020/03/14/how-to-monitor-machine-learning-models/)
2 changes: 1 addition & 1 deletion docs/7. Observability/7.3. Lineage.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,4 @@ To build a world-class lineage system, consider these best practices:

- **[Example from the MLOps Python Package](https://github.com/fmind/mlops-python-package/blob/main/src/bikes/io/datasets.py)**
- [MLflow Tracking Dataset](https://mlflow.org/docs/latest/tracking.html#tracking-datasets)
- [OpenLineage](https://openlineage.io/) and [Marquez](https://marquezproject.github.io/)
- [OpenLineage](https://openlineage.io/) and [Marquez](https://marquezproject.ai/)
4 changes: 2 additions & 2 deletions docs/7. Observability/7.5. Explainability.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ description: Explore the significance of explainability in AI/ML, learn how to u

Explainability techniques are typically categorized by their scope:

- **[Local Explainability](https://censius.ai/blogs/global-local-cohort-explainability#blogpost-toc-13)**: Explains a *single* prediction. It answers the question: "Why did the model make this specific decision for this particular input?" This is vital for analyzing individual cases, such as understanding why a specific customer's loan application was denied.
- **[Local Explainability](https://christophm.github.io/interpretable-ml-book/shap.html)**: Explains a *single* prediction. It answers the question: "Why did the model make this specific decision for this particular input?" This is vital for analyzing individual cases, such as understanding why a specific customer's loan application was denied.
- **Example**: [SHAP (SHapley Additive exPlanations)](https://shap.readthedocs.io/en/latest/) calculates the impact of each feature on an individual prediction, showing which factors pushed the prediction higher or lower.

- **[Global Explainability](https://censius.ai/blogs/global-local-cohort-explainability#blogpost-toc-11)**: Explains the *overall* behavior of a model across the entire dataset. It answers the question: "What are the most important features driving the model's predictions in general?" This is useful for understanding the model's core logic.
- **[Global Explainability](https://christophm.github.io/interpretable-ml-book/feature-importance.html)**: Explains the *overall* behavior of a model across the entire dataset. It answers the question: "What are the most important features driving the model's predictions in general?" This is useful for understanding the model's core logic.
- **Example**: Feature importance plots from tree-based models provide a global view by ranking features based on their average contribution to the model's accuracy.

Effective model analysis often requires both: global explainability to understand the general strategy of the model and local explainability to audit and trust individual outcomes.
Expand Down
14 changes: 14 additions & 0 deletions mise.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions mise.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ actionlint = "latest"
dprint = "latest"
gitleaks = "latest"
lefthook = "latest"
lychee = "latest"
# The course teaches readers to pin Python 3.14; the site that teaches it pins the same
# interpreter, so `mise-action` in CI provisions it instead of inheriting the runner's.
python = "3.14"
Expand Down Expand Up @@ -81,6 +82,17 @@ run = ["actionlint", "zizmor --offline .github/workflows/"]
description = "Build the site in strict mode to catch broken links and config"
run = "uv run mkdocs build --strict"

[tasks."check:links"]
description = "Check external links in the README and every chapter (lychee)"
# Deliberately NOT in `check`. It takes minutes, hits ~700 external URLs, and most of
# what it reports is other people's rate limiting: a full run found 63 failures, of which
# 37 were HTTP 429 and 14 were bot-blocking 403s against only 9 genuinely dead links.
# Wiring that into the commit gate would train everyone to ignore a red check. It runs
# monthly and on demand from `.github/workflows/links.yml` instead, where a human reads it.
# 429 is accepted on purpose: a host that rate-limits a scanner is a host that is up, so
# treating it as a failure would report the opposite of what the check exists to find.
run = "lychee --no-progress --max-concurrency 8 --timeout 20 --accept 200..=299,429 README.md AGENTS.md 'docs/**/*.md'"

[tasks."check:format"]
description = "Check formatting and config validity"
run = [
Expand Down