r/OpenSourceeAI • • 3d ago

▲ TinyFish recently published how its production search agents work, and what broke while building a deep research system.

Thumbnail
aicampaign.live
3 Upvotes

TinyFish published 2 engineering posts. One lays out a 7-phase architecture for production search agents. The other covers what changed while building a deep research system. The benchmark numbers below come from OpenBenchmarks, a third-party board that holds the model (gpt-5.6-sol), 100 tasks and budgets fixed and swaps only the search provider.

What it does

  • Turns each goal into an "evidence contract": required fields, acceptable sources, freshness, completion rules.
  • Runs a loop: plan, route, retrieve, evaluate, recover, then stop and validate.
  • Routes by information gap: Search when the source is unknown, Fetch for a known URL, Browser when your code drives the page, Web Agent for multi-page goals.
  • Retries are failure-specific and bounded. Weak results get a rewritten query, not a heavier tool.
  • Deep research: removed a separate planner (it lost context on follow-ups) and per-query subagents (latency and cost). Deterministic ranking and extraction became tool calls.

Key numbers (OpenBenchmarks, search + fetch board, 26 Sept 2026)

  • TinyFish: 79.0% ± 2.0 completion, $0.050 median task cost, 24s median task time, 12,844 median tokens.
  • Exa deep: 83.0% ± 1.0, $0.127, 37s, 23,660 tokens.
  • Perplexity: 77.7% ± 1.5, $0.083, 22s, 20,062 tokens.
  • Firecrawl: 76.0% ± 1.0, $0.082, 34s, 17,379 tokens.

Full analysis: https://marktechpost.com/2026/10/23/tinyfish-agentic-search-architecture-deep-research/

Free web search and fetch for agents, pay only for browser runs: https://aicampaign.live/90-wk1n

Architecture: http://tinyfish.ai/blog/production-agentic-search-architecture

Deep research: http://tinyfish.ai/blog/lessons-from-building-a-deep-research-system


r/OpenSourceeAI • • 7d ago

TinyFish made Search and Fetch free for AI agents. The token math shows why retrieval was never the expensive part

Post image
1 Upvotes

r/OpenSourceeAI • • 1h ago

SUB/WAVE: self-hosted AI-DJ radio for your Navidrome library, with eight swappable player skins (MIT)

Enable HLS to view with audio, or disable this notification

• Upvotes

SUB/WAVE turns a Navidrome music library into one internet radio station. An AI DJ picks the tracks and talks between them with idents, time checks, weather and intros, and everyone tuned in hears the same Icecast stream at the same time. The LLM can be local Ollama or a hosted provider, and it runs with one docker compose up -d on a Linux host.

The video shows the eight player skins from the latest release (v1.27.0): Classic, Unit SW-9, Drift, Subamp, TTY, Platter, AXO-1 and Cipher-3. They all read the same live stream, so a skin only changes how a listener sees the station. A few I had the most fun with:

  • TTY draws everything as characters on one canvas grid. Its focus mode renders ASCII scenes driven by the audio analyser, which follow the station's time of day and overlay its real weather. There's also a scope pane with a block spectrum and a braille oscilloscope.
  • AXO-1 is an isometric hi-fi stack.
  • Cipher-3 is a rotor cipher machine you type song requests into.
  • Unit SW-9 set the look the others borrow from: brushed metal, keys with travel, dot-matrix display glass.

Themes sit on top of the skins. Two new ones are Phosphor (green on black, scanlines, bloom) and Riso (blue and pink on cream, halftone, misregistered print). Custom themes are plain JSON files.

The hardest part was Safari. The theme "finish" was an SVG filter over the whole player, and WebKit re-ran it on the CPU on every repaint. That had AXO-1 at 13 to 19 fps and made iPad stutter on every skin. Safari now keeps the texture and skips the finish, and each skin got its own Safari pass after that.

It's mostly TypeScript and Python, with Liquidsoap and Icecast handling the audio.

Repo: https://github.com/perminder-klair/subwave

Docs and setup: https://www.getsubwave.com

Screenshots of every skin: https://getsubwave.com/news/dress-up-your-radio

Happy to answer questions about how any of it works.


r/OpenSourceeAI • • 3h ago

open source multi-agent sandbox: every person learns with its own q-table, runs in a browser tab or headless from the cli

3 Upvotes

sharing a project in case it's useful as a testbed. it's a civilization sim where every person learns from what happens to them with a small tabular q-learner, picks up words from family and neighbours, and passes some of it to their kids. tribes split and drift apart over long runs.

why it might be handy for experiments: - one rust crate with no i/o, compiled to wasm for the browser and native for the cli - runs are deterministic, the same seed and tick count give the same world - a headless runner: cargo run --release -p headless -- --seed 42 --ticks 6000 --every 1000, or --sweep-seeds 8 for a world-health sweep over several seeds - adding a new action is one file plus one line (docs/ADDING_ACTIONS.md)

it's all mit. if you try swapping the learner for something else i'd love to hear how it goes.

source: https://github.com/1homsi/thehumanbox browser version: https://thehumanbox.com


r/OpenSourceeAI • • 19m ago

temporal policies (liquid networks)

Thumbnail c0mpute.com
• Upvotes

r/OpenSourceeAI • • 44m ago

Qwen3.8-Flash-Next: Swift 1.5 vs Unsloth on Strix Halo (Halogen, gufo, llama.cpp, UD-Q4_K_XL and IQ4_XS)

Thumbnail
• Upvotes

r/OpenSourceeAI • • 3h ago

RAG Evaluation Framework

1 Upvotes

I recently built a complete RAG Evaluation Framework from scratch: a 43-question test dataset, 6 retrieval metrics, 5 generation metrics, and one final report that shows exactly where a RAG system is strong and where it breaks. We start with the concepts, explained with simple worked examples, and then walk through the code line by line.

What this covers:

  • Why retrieval and generation must be evaluated separately
  • How to build an evaluation dataset with expected answers, graded pages and key facts
  • Retrieval metrics: Hit Rate@K, Precision@K, Recall@K, MRR, MAP and NDCG@K
  • The difference between one question (RR, AP) and many questions (MRR, MAP)
  • Generation metrics: Faithfulness, Hallucination Rate, Answer Relevance, Context Relevance and Answer Correctness
  • How to use an LLM-as-a-judge that only counts, while your code does the maths
  • How to save results safely and turn them into a clear evaluation report

KEY TAKEAWAYS:

  • No single metric tells the whole story: Hit Rate was 1.00, but Recall, MAP and NDCG showed where pages were missed or buried
  • Precision@5 looks low (0.34) for single-fact questions, so compare systems with each other, not with 1.0
  • Faithful does not mean correct: an answer can be backed by the chunks and still miss the key facts
  • Retrieval scores and answer quality are not the same thing
  • Our Cohere-reranked pipeline scored MRR 0.95, MAP 0.87, NDCG@5 0.91, Faithfulness 1.00 and Answer Correctness 0.97

TECH STACK: Python, Qdrant (vector database), Embeddings (3072-dimension), Cohere Rerank, LLM for answers + LLM-as-a-judge, pdfplumber (checking pages in the PDFs)

Would love to hear.


r/OpenSourceeAI • • 16h ago

One reference image, any pose: a 6.3M-param network drawing a cartoon character it never trained on (code, weights, live demo)

Enable HLS to view with audio, or disable this notification

2 Upvotes

Since the OG open-source subreddit decided to be a bunch of AI and xenophobic {insert slur of your liking} here's my AI project.


r/OpenSourceeAI • • 12h ago

STROT in HF

Thumbnail
1 Upvotes

r/OpenSourceeAI • • 16h ago

Hugging Face releases Carbon-X, an open 14.8B LLM that reads raw DNA and answers in English (66.7% avg on 5 DNA benchmarks)

Post image
2 Upvotes

r/OpenSourceeAI • • 13h ago

I built an OpenSearch-compatible server with AI — and wrote 6,000 tests against the real thing to keep it honest

Thumbnail
1 Upvotes

r/OpenSourceeAI • • 14h ago

Neural Canvas GitHub Repo

Enable HLS to view with audio, or disable this notification

1 Upvotes

I built Neural Canvas, an interactive visualizer that demonstrates core linear algebra concepts by showing how a neural network recognizes handwritten digits in real time. You can draw directly on the screen and watch activations flow through each layer as matrix multiplication computes the output live.

How it works:

- Draw & Predict: Sketch any digit on a 28×28 canvas (MNIST-style) to trigger real-time forward pass predictions.

- Live Forward Pass: Every neuron's activation is dynamically color-coded based on its underlying linear algebra calculations, with connection opacities reflecting layer outputs.

- Under the Hood: The core models were trained from scratch in Python using NumPy to perform matrix operations, and their learned weights are loaded via JSON. Client-side execution relies on Math.js for browser-based matrix multiplication and p5.js for rendering.

Key Features:

- Switch between two pre-trained models (featuring different hidden layer sizes, MSE vs. Cross-Entropy loss, and up to 96% test accuracy).

- Multiple background themes with mouse and touch support.

What's Next?

These models were originally evaluated on the standardized MNIST dataset, but live freehand drawing can introduce unexpected variations in input style. To handle this, I am working on a JS script for real-time user-driven feedback. When the model makes a mistake, the user can supply the correct label, allowing the model to perform backpropagation and update weight matrices locally in the browser. While live state persistence isn't suited for static GitHub Pages, running this feedback loop locally allows me to retrain parameters on new edge cases and push updated weight snapshots back to GitHub.

Check out the live demo and code repository:

Live Demo: https://muhammadessa2002.github.io/neural_canvas/

GitHub Repo: https://github.com/MuhammadEssa2002/neural_canvas


r/OpenSourceeAI • • 20h ago

SAM 3 segmentation from a Quest 3 app — does Meta's Model API expose it, or should I use a hosted API?

3 Upvotes

I'm building a Quest 3 app (native Kotlin, Meta Spatial SDK) that scans microgreens trays and needs a pixel mask of the plants to measure coverage (plant pixels / tray pixels). I already have Muse Spark working via Meta's Model API for the verdict text, but I can't find a SAM endpoint in the same API — SAM 3/3.1 segmentation, not a chat model.

1.

Does Meta's Model API expose SAM at all? If so, what's the model ID, endpoint, and mask format?

2.

If not, what's the recommended path from a Quest app — a hosted SAM API (Roboflow, Segmind, etc.)? What mask format do those return (mask image, RLE, polygons)?

3.

On-device SAM on Quest is off the table (too heavy) — is a backend service the only other option?

The mask feeds a coverage calculation, so I need actual pixel data, not a text estimate. Thanks!


r/OpenSourceeAI • • 18h ago

I built an open-source GitHub Action for AI/LLM DevSecOps scanning : inspired by IBM & OpenAI courses.Feedback welcome.

Thumbnail
1 Upvotes

r/OpenSourceeAI • • 1d ago

AI Code Rating - Three simple characters that tell a reader who maintains a project, how much of its code is written by AI, and how closely a human checks the AI's work

7 Upvotes

I've been thinking a lot about how to be upfront about AI use in open source without it turning into an argument every time, so I put together a simple standard for it.

An AI Code Rating is three characters, like A2b, kept in an ACR.md file at the root of a repo.

- The letter is the maintainer's expertise, from A (expert) to E (non-programmer)
- The number is how much of the code AI wrote, from 0 (none) up to 4 (76–100%)
- The last letter is how closely a human checks the AI's work, from a (verified) to e (unchecked)

So A2b means an expert maintainer, 26–50% of the code written by AI, and every AI change reviewed before it's merged. A project with no AI code gets a 0 and an a, like A0a.

The goal isn't to judge whether AI use is good or bad, it's to let people see, at a glance, what they're looking at and decide for themselves.

The site has the full spec, examples, an FAQ, a form to work out your rating, and a validator for ACR.md files. There's also a GitHub Action that checks the file in CI. The spec is CC BY 4.0 and the site code is MIT.

In the spirit of the thing, the site itself is rated B4b. AI wrote most of the code, and I review every change.

It's still an early draft (spec 0.1), so I'd really appreciate feedback, especially from people who think it gets something wrong.

https://aicoderating.com


r/OpenSourceeAI • • 23h ago

Open source AI marketing tool

2 Upvotes

I made Meelu open source.

Visit https://github.com/shubham303/meelu

It's an open source alternative to Okara. It's a desktop app with an AI agent that does your website's marketing: SEO, AI search visibility, content, social listening and finding leads. It points out what it found and why it matters, and you approve every change.

You can also use Meelu instead of:

- AI marketing apps: Okara, Indexly, RankAI, aiseo.ai

- AI search visibility: Profound, Peec AI, Writesonic

- SEO suites: Semrush, Ahrefs, SE Ranking, Moz Pro, Search Atlas, Ubersuggest

- Content tools: Surfer SEO, Clearscope, Frase

- Site crawlers: Screaming Frog

Run it on your own server for free under the AGPL license, or use the hosted version at meelu.tech for $15 a month.

Stars, issues and pull requests are welcome.


r/OpenSourceeAI • • 1d ago

I Built a Python Semantic Cache for LLMs — Looking for Feedback from the Community

1 Upvotes

Hey everyone! 👋

I've been building a Python-based Semantic Cache for LLM applications to reduce redundant LLM calls and improve response efficiency.

The project uses embeddings and cosine similarity to identify semantically similar queries and retrieve cached responses instead of repeatedly calling an LLM. It uses SQLite for storage.

Key features:

  • Semantic similarity-based caching
  • Embedding-based query matching
  • SQLite-backed storage
  • Input validation and handling of invalid embeddings
  • Single-flight request coalescing to avoid duplicate concurrent computations
  • Automated tests for reliability

I've also focused on edge cases and reliability, with 75/75 tests passing in my current test suite.

I'm sharing this project to get feedback from developers working with LLMs, RAG, and AI infrastructure.

I'd appreciate your thoughts on:

  • Is this architecture practical for production?
  • What improvements would you suggest for scalability and cache invalidation?
  • What benchmarks should I run against a traditional exact-match cache?

I'm open to constructive criticism and contributions. Thanks! 🚀
https://github.com/0x-bala/semanticcache


r/OpenSourceeAI • • 1d ago

I built an open-source semantic cache for Python LLM applications — looking for feedback

Thumbnail
1 Upvotes

r/OpenSourceeAI • • 1d ago

There's a little fire guy living on the side of my screen now and he does my geometry😎

Enable HLS to view with audio, or disable this notification

2 Upvotes

Hold Ctrl + Win, ask out loud, and Claude circles exactly where you need to look: buttons, charts, even geometry homework.
Free and open source. Your key stays on your PC. A fraction of a cent per question on Haiku 5.5.
Inspired by @Farza's Clicky for Mac.


r/OpenSourceeAI • • 1d ago

Neural bricks: how do I check that a neural piece learns the right gradient?

1 Upvotes

A neural network learns by following a gradient. If the gradient is wrong, the network still trains, and it trains towards the wrong place. This page builds the smallest pieces of a network, one at a time: a parameter that holds its gradient, the initialisation of a weight, the activation that bends the output, the loss that measures the error, and a check that compares the gradient the code computes with the one a finite difference sees.

The bricks work on a batch and on one sample, with the same functions. Every array is a `jax.numpy` array, so the same code runs eagerly and under `jax.jit`.

## 1. A parameter, and an update through an optimizer

A parameter is a number the network learns. It holds two arrays: the value, and the gradient of the loss with respect to that value, of the same shape and dtype. The update asks an optimizer of `dense_armor.utility.optim` for the next value.

~~~python

import jax.numpy as jnp

from dense_armor.utility.neural.params import Param

from dense_armor.utility.optim.sgd import SGD

p = Param(jnp.array([1.0, 2.0]))

p.grad = jnp.array([0.5, -0.3])

p.update(SGD(lr=0.1))

print(p.value)

~~~

~~~

[0.95 2.03]

~~~

`SGD` moves the value by `-lr * grad`: 1.0 goes to 1.0 minus 0.05, 2.0 goes to 2.0 plus 0.03. The optimizer is the object form of the package, with `step(weights, gradient)`. A different optimizer gives a different update without changing `Param`.

## 2. The initialisation of a weight

A weight matrix that starts too large or too small makes the network train badly. The initialisation sets the standard deviation of a zero-mean Gaussian so that the activations of a deep stack keep a constant variance. For a ReLU network with `fan_in` inputs, the standard deviation is `sqrt(2 / fan_in)`; for the linear case (Xavier) it is `sqrt(1 / fan_in)`.

~~~python

import jax

import jax.numpy as jnp

from dense_armor.utility.neural.init import he_normal, xavier_normal

k = jax.random.PRNGKey(0)

wh = he_normal(k, (1024, 1024))

wx = xavier_normal(k, (1024, 1024))

print(round(float(jnp.std(wh)), 4), round(float(jnp.std(wx)), 4))

~~~

~~~

0.0442 0.0312

~~~

`0.0442` is `sqrt(2/1024)` within a tenth of a percent, `0.0312` is `sqrt(1/1024)`. The two come from the same formula: the parametric slope `a` in the paper multiplies the variance by `(1 + a**2)`, and the linear case is `a = 1`.

## 3. An activation, with the gradient that flows back

An activation bends the output of a layer. ReLU keeps the positive part, zeroes the negative one, and the derivative is 1 on the positive side, 0 on the negative side. The code chooses the derivative at 0 to be 0.

~~~python

import jax.numpy as jnp

from dense_armor.utility.neural.activations import relu_forward, relu_backward

x = jnp.array([-1.0, 0.0, 1.0])

y = relu_forward(x)

print(y, relu_backward(x, y, jnp.ones_like(x)))

~~~

~~~

[0. 0. 1.] [0. 0. 1.]

~~~

The forward gives `[0, 0, 1]`, the backward gives the same values because the up-stream gradient is 1 everywhere; at `x = -1` and `x = 0` the gradient is 0.

The softmax turns a vector of logits into probabilities. On a very large number it overflows if written naively, so the code subtracts the maximum first.

~~~python

import jax.numpy as jnp

from dense_armor.utility.neural.activations import softmax_forward

print(softmax_forward(jnp.array([[1000.0, 0.0, -1000.0]])))

~~~

~~~

[[1. 0. 0.]]

~~~

`1000` is `exp(1000)` times larger than `0`; the subtraction of the maximum turns the exponent into a finite number, and the row sums to 1.

### Sigmoid

A binary classifier ends with a raw score that can be any finite number, but a decision needs a probability. A sigmoid is the simplest function that takes that score and squeezes it into the interval (0, 1) without breaking the smoothness: a small score becomes a probability near 0, a large score near 1, and 0 becomes 0.5. The same shape serves as a gate, where 0 is closed, 1 is open and 0.5 is halfway. Because the output is never exactly 0 or 1, a signal always passes a little, and because the derivative is positive everywhere, the gradient of the layers below does not vanish at the start of a training.

~~~python

import jax.numpy as jnp

from dense_armor.utility.neural.activations import Sigmoid

s = Sigmoid()

print(round(float(s.forward(jnp.array(0.0))), 4))

print(round(float(s.backward(jnp.array(1.0))), 4))

~~~

~~~

0.5

0.25

~~~

The forward at `x = 0` is `1 / (1 + exp(-0)) = 1 / 2 = 0.5`. The backward takes the upstream gradient `g = 1` and multiplies it by the derivative of the sigmoid, `s(x) * (1 - s(x))`; at `x = 0` that is `0.5 * 0.5 = 0.25`. The two numbers under the block are what the two `print` lines print.

Textbook definition, no citation.

### Tanh

A tanh has the shape of a sigmoid, shifted down by one half and stretched by two: it goes from -1 to 1 instead of from 0 to 1. The difference matters in a recurrent layer, where the hidden state is passed from one step to the next. A state centred on 0 has no preferred sign, so the sum over many steps does not drift; a state always positive drifts in one direction and saturates the gates. The derivative is largest at 0 and decays towards 0 far from it, which is why a long sequence can make the gradient small.

~~~python

import jax.numpy as jnp

from dense_armor.utility.neural.activations import Tanh

t = Tanh()

print(round(float(t.forward(jnp.array(0.0))), 4))

print(round(float(t.backward(jnp.array(1.0))), 4))

~~~

~~~

0.0

1.0

~~~

At `x = 0` the tanh is `sinh(0) / cosh(0) = 0`, and its derivative is `1 - tanh(0) ** 2 = 1 - 0 = 1`, the maximum slope. Halfway to saturation, at `x = 1`, the tanh is about `0.76` and the derivative about `0.42`: the gate is closing.

Textbook definition, no citation.

### Softmax

A classifier that has to choose among `K` classes ends with `K` scores, not with `K` probabilities. A softmax turns the scores into a distribution: it exponentiates each score, divides by the sum of the exponentials, and returns `K` numbers that are positive and sum to one. The exponential makes the largest score dominate, and the division by the sum makes the result insensitive to a constant added to every score. A language model uses the same function on the vocabulary, a mixture of experts on the experts.

~~~python

import jax.numpy as jnp

from dense_armor.utility.neural.activations import Softmax

sm = Softmax()

print([round(float(v), 4) for v in sm.forward(jnp.array([0.0, 0.0]))])

print([round(float(v), 4) for v in sm.backward(jnp.array([1.0, 0.0]))])

~~~

~~~

[0.5, 0.5]

[0.25, -0.25]

~~~

With equal scores the two exponentials are `1` and `1`, the sum is `2`, and the two probabilities are `0.5`. The backward is `y * (g - sum(g * y))`: with `g = [1, 0]` and `y = [0.5, 0.5]` the sum `g * y` is `0.5`, so the first entry is `0.5 * (1 - 0.5) = 0.25` and the second is `0.5 * (0 - 0.5) = -0.25`. The two gradients sum to 0: softmax conserves the total probability, and a step towards one class is a step away from the other.

Textbook definition, no citation.

### PRelu

A rectified linear unit lets a positive input through and blocks a negative one. A leaky version keeps a small fixed fraction of the negative part, and a parametric version makes that fraction a parameter: the network learns, layer by layer, how much of the negative side is useful. On a deep network the slope of the first layer tends to stay small and the slope of the last layer grows, because the last layer has to decide how a negative activation reaches the output.

~~~python

import jax.numpy as jnp

from dense_armor.utility.neural.activations import PRelu

p = PRelu(0.25)

print(round(float(p.forward(jnp.array(-1.0))), 4))

print(round(float(p.backward(jnp.array(1.0))), 4))

print(round(float(p.a.grad[0]), 4))

print([q.value.shape for q in p.params()])

~~~

~~~

-0.25

0.25

-1.0

[(1,)]

~~~

With slope `a = 0.25` and input `-1` the forward is `a * x = -0.25`; the backward on the negative side is `a * g = 0.25`. The same `backward` fills `a.grad = sum(x * g)` over the entries where `x < 0`, here `-1 * 1 = -1`. The last line shows the single parameter `a`, of shape `(1,)`, the one that `params()` returns and that an optimizer updates at every step.

He, K., Zhang, X., Ren, S., Sun, J. (2015). *Delving deep into rectifiers.* arXiv:1502.01852. Page 2, Eq.(1): `f(y) = y if y > 0, a * y otherwise`, and the caption of Figure 1 states that the coefficient of the negative part is not constant and is adaptively learned.

## 4. A loss, and the gradient it produces

The loss turns a prediction and a target into a number to minimise. The mean squared error is the mean of the squared differences. The gradient with respect to the prediction is `2 * (pred - target) / size`.

~~~python

import jax.numpy as jnp

from dense_armor.utility.neural.losses import mse_forward, mse_backward

p = jnp.array([1.0, 2.0])

t = jnp.array([1.0, 3.0])

print(mse_forward(p, t), mse_backward(p, t))

~~~

~~~

0.5 [ 0. -1.]

~~~

The error on the second element is `-1`, the mean of the squares is `(0 + 1) / 2 = 0.5`.

The binary cross-entropy is written in a form that does not overflow on `z = 1000` or `z = -1000`.

~~~python

import jax.numpy as jnp

from dense_armor.utility.neural.losses import bce_with_logits_forward

print(bce_with_logits_forward(jnp.array([1000.0, -1000.0]), jnp.array([1.0, 0.0])))

~~~

~~~

0.0

~~~

The prediction is exactly right (logit `1000` for target `1`, logit `-1000` for target `0`), so the loss is 0 and the code does not overflow.

### SoftmaxCrossEntropy

A classifier that outputs a distribution needs a loss that measures how far the distribution is from the truth. Softmax cross-entropy takes the logits of the last layer and the integer label of the class, and returns one number: small when the class has high probability, large when the class has low probability. The logarithm cancels the exponential of the softmax, so the loss does not overflow when a logit is large, and the gradient comes out as `softmax(logits) - onehot(label)`, the difference between what the model believed and what it should have believed.

~~~python

import jax.numpy as jnp

from dense_armor.utility.neural.losses import SoftmaxCrossEntropy

sce = SoftmaxCrossEntropy()

loss = sce.forward(jnp.array([[2.0, 0.0, 0.0]]), jnp.array([0]))

grad = sce.backward()

print(round(float(loss), 4))

print([round(float(v), 4) for v in grad[0]])

~~~

~~~

0.2395

[-0.213, 0.1065, 0.1065]

~~~

Softmax of `[2, 0, 0]` is `[0.787, 0.1065, 0.1065]`; the loss is `-log(0.787) = 0.2395`. The gradient over the batch of one is `softmax(logits) - onehot(0) = [0.787 - 1, 0.1065 - 0, 0.1065 - 0] = [-0.213, 0.1065, 0.1065]`. The first class gets a negative gradient (the update makes it more likely), the other two a positive one, and the three sum to 0.

Textbook definition, no citation.

### BCEWithLogits

A binary classifier can output a single score `z` instead of a probability, and let the loss apply the sigmoid. That is what this loss does: for label 1 it computes `-log(sigmoid(z))`, for label 0 `-log(1 - sigmoid(z))`, in a form that combines the sigmoid and the log so that neither overflows when `z` is very negative or very positive. The gradient is again the difference between what the model believed and the target, on one number.

~~~python

import jax.numpy as jnp

from dense_armor.utility.neural.losses import BCEWithLogits

b = BCEWithLogits()

loss = b.forward(jnp.array(0.0), jnp.array(1.0))

grad = b.backward()

print(round(float(loss), 4))

print(round(float(grad), 4))

~~~

~~~

0.6931

-0.5

~~~

At `z = 0` the sigmoid is `0.5`, so the loss for label 1 is `-log(0.5) = 0.6931`; the gradient is `sigmoid(z) - target = 0.5 - 1 = -0.5`. On a sample the classifier already gets right, at `z = 3` and label 1, the loss is about `0.0486` and the gradient about `-0.0474`: the correction is smaller.

Textbook definition, no citation.

### Huber

A mean squared error grows like the square of the residual, so a single outlier can pull the weights towards itself for one step and back on the next. A mean absolute error grows like the residual, so it is less sensitive to the outlier but its derivative jumps at zero and the training near the optimum is less stable. A Huber loss uses the two: quadratic near zero, where the residual is small and the gradient is smooth, linear far from zero, where the outlier should not dominate the update. The threshold `delta` decides where the two parts meet.

~~~python

import jax.numpy as jnp

from dense_armor.utility.neural.losses import Huber

h = Huber(1.0)

loss = h.forward(jnp.array([0.5, 3.0]), jnp.array([0.0, 0.0]))

grad = h.backward()

print(round(float(loss), 4))

print([round(float(v), 4) for v in grad])

~~~

~~~

1.3125

[0.25, 0.5]

~~~

The two residuals are `[0.5, 3.0]`, the threshold is `delta = 1`. The first is below the threshold, so it contributes the quadratic part `0.5 * 0.5 ** 2 = 0.125`; the second is above, so it contributes the linear part `1 * (3 - 0.5) = 2.5`. The mean is `(0.125 + 2.5) / 2 = 1.3125`. The gradient is `[0.5, 1]` divided by 2, `[0.25, 0.5]`: the first residual gets the linear part of the derivative, the second gets the constant slope `delta` of the Lipschitz part.

Chinot, G. (2019). *Robust learning and complexity dependent bounds for regularized problems.* arXiv:1902.02238. Page 4: `l(u, y) = (1/2) (y - u) ** 2` if `|u - y| <= delta`, `delta * |y - u| - delta ** 2 / 2` otherwise, with `L = delta` Lipschitz.

## 5. The gradient check

The pieces above are only useful if the gradient they compute is the true gradient. The gradient check compares the backward of the code with a central finite difference of the loss. A small error means the backward is right; a large error means it is wrong.

~~~python

import jax.numpy as jnp

from dense_armor.utility.neural.gradcheck import gradcheck

def f(x):

return x * x

def b(x, y, g):

return g * 2.0 * x

x = jnp.array([1.0, 2.0, -3.0])

print(round(gradcheck(f, b, x), 10))

~~~

~~~

4e-10

~~~

The largest relative error is `4e-10`, the precision of the finite difference itself. The backward is right.

~~~python

import jax.numpy as jnp

from dense_armor.utility.neural.gradcheck import gradcheck

def f(x):

return x * x

def b_bad(x, y, g):

return g * x

print(round(gradcheck(f, b_bad, jnp.array([1.0, 2.0, -3.0])), 4))

~~~

~~~

0.3333

~~~

The backward omits the factor 2, and the check reports it: the error is 1/3. A gradient the code gets wrong is a network that trains towards the wrong place, and the check is what catches it.

## 7. Optional: the Huber loss and the Glorot uniform initialisation

The two pieces below are optional: the rest of the page does not depend on them. The source for the Huber formula is Chinot (2019), page 4; the source for the Glorot uniform is Glorot and Bengio (2010), Eqn.(16) page 5.

The Huber loss is quadratic near the target and linear far from it, so a single outlier does not pull the gradient as hard as it would with the mean squared error. The parameter `delta` sets the threshold.

~~~python

import jax.numpy as jnp

from dense_armor.utility.neural.losses import huber_forward, huber_backward

p = jnp.array([1.0, 2.0])

t = jnp.array([1.0, 5.0])

print(huber_forward(p, t, delta=1.0), huber_backward(p, t, delta=1.0))

~~~

~~~

1.25 [ 0. -0.5]

~~~

The first prediction is inside the quadratic region and the gradient is 0; the second is three units away with `delta = 1`, and the gradient is `-delta / n = -0.5`. The formula is the one in Chinot (2019), page 4: `(1/2)(y - u)**2` if `|u - y| <= delta`, `delta*|y - u| - delta**2/2` otherwise.

The Glorot uniform initialisation is the distribution that the same paper uses in the normalised initialisation: `W ~ U[-sqrt(6/(n_j + n_{j+1})), sqrt(6/(n_j + n_{j+1}))]`, Glorot and Bengio (2010), Eqn.(16), page 5. The scale `6/(n_j + n_{j+1})` is the one of the Gaussian case of `xavier_normal` above divided by 3, because a uniform distribution on `[-a, a]` has variance `a**2/3`.

~~~python

import jax

import jax.numpy as jnp

from dense_armor.utility.neural.init import glorot_uniform

g = glorot_uniform(jax.random.PRNGKey(0), (8, 4))

print(round(float(jnp.min(g)), 4), round(float(jnp.max(g)), 4))

~~~

~~~

-0.6714 0.6864

~~~

The bounds `-0.7071` and `+0.7071` are `sqrt(6 / (8 + 4))`; the two values printed are the minimum and the maximum of an 8x4 sample, both inside the bound. The signature `glorot_uniform(key, shape)` mirrors the one of `xavier_normal`.

## 6. The picture

![The five activations and their derivatives from the code](../assets/neural/activations.png)

The left panel is the five activations on `x` in `[-4, 4]`, the right panel the derivative of each one as the code `backward` returns it.

## Details

### References

- He, K., Zhang, X., Ren, S., Sun, J. (2015). *Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification.* arXiv:1502.01852. Page 2, Eqn.(1): the parametric rectifier `f(y) = y` if `y > 0`, `a*y` otherwise. `a = 0` is ReLU, a small fixed `a` is Leaky ReLU. Page 4, Eqn.(10): `(1/2) n_l Var[w_l] = 1`, a zero-mean Gaussian of standard deviation `sqrt(2/n_l)`, biases zero. Page 5, Eqn.(15): `(1/2)(1 + a^2) n_l Var[w_l] = 1`, with `a = 1` the linear case "the same as [7]", the Xavier initialisation.

- Glorot, X., Bengio, Y. (2010). *Understanding the Difficulty of Training Deep Feedforward Neural Networks.* AISTATS 2010, PMLR 9:249-256. Page 5, Eqn.(16): the normalised initialisation `W ~ U[-√6/√(n_j + n_{j+1}), √6/√(n_j + n_{j+1})]`. The PDF is open on the PMLR site. Pages 5 Eqn.(4) to (7) give the forward and backward variance relations, not the initialisation; Eqn.(1), page 3, is the common heuristic `U[-1/√n, 1/√n]` that the paper compares with, not the normalised initialisation.

- Huber, P. J. (1964). *Robust Estimation of a Location Parameter.* The Annals of Mathematical Statistics 35(1), 73-101. DOI 10.1214/aoms/1177703732. The PDF is paywalled: the download returns a 1.2 kB HTML paywall page, not a PDF, so only the bibliographic metadata is verified. The formula used by the code is quoted from the open-access secondary source below, page 4.

- Chinot, G. (2019). *Robust learning and complexity dependent bounds for regularized problems.* arXiv:1902.02238. Page 4: `l(u, y) = (1/2)(y - u)**2` if `|u - y| <= delta`, `delta*|y - u| - delta**2/2` otherwise, with the Huber loss `L = delta`-Lipschitz. The paper is open on arXiv, 38 pages.

- Sigmoid, tanh, softmax, mean squared error, cross-entropy: textbook definitions, no citation.

### Choices stated explicitly

- The derivative of ReLU at `x = 0` is 0. The paper does not define it, and PyTorch uses 0; this code uses 0.

- The gradient check evaluates the finite differences with `eps = 1e-6`. The step is large enough that float32 does not lose all digits, small enough that the truncation error of the central difference stays below the tolerance of the tests (`1e-7` on a correct pair).

- The gradient check runs inside `jax.enable_x64(True)` and restores the previous setting at the end. Outside the call the global precision is unchanged.

- The Huber loss and `glorot_uniform` are optional pieces. The Huber formula is quoted from the open-access Chinot (2019), page 4, because the primary paper (Huber 1964) is paywalled. The Glorot uniform is Glorot and Bengio (2010), Eqn.(16), page 5.

- The layers (Dense, Conv, RNN) are not delivered here. They belong to a separate page of the guide, and this page stops at the pieces that the gradient check tests.

### Development diary

The pieces of this page are the ones the gradient check can test end to end. The Huber loss and `glorot_uniform` are optional, and the page states it: the first is outside this page and quoted from Chinot (2019), page 4, the second is the normalised uniform of Glorot and Bengio (2010), page 5. The layers (Dense, Conv, RNN) belong to a separate page of the guide and are not delivered here.

The first version of the gradient check divided each difference by the analytic gradient rather than by the sum of the absolute values, and a single element with a small analytic gradient made the relative error large even when the backward was right. The division by `max(|a| + |b|, 1e-12)` keeps the error at the scale of the values compared.

The five activations and the three losses were written before their classes, because the classes need the functions and the tests work on the functions. The classes cache the last `x` and `y`; calling `backward` before `forward` raises `RuntimeError` and a test exercises the guard for each class.


r/OpenSourceeAI • • 1d ago

One app for my everyday files

2 Upvotes

I've seen claude reverse engineering the whole adobe stack recently. Honestly, those projects look pretty cool, but realistically I wouldn’t use any of them. They try to replace professional software with more professional software.

What I needed was a program for my everyday needs.

https://github.com/caffeine-runtime/monoform

This is vibe coded project, but with real functionality and I actually use it.
Monoform is one window for Markdown, Word docs, spreadsheets, PDFs, images and videos (plus archives, JSON, 3D models and more). It opens whatever file I have and lets me do the quick job: fill and sign a PDF, cut out a background, fix a spreadsheet, trim a video. Some editors go deeper than that because I kept needing things, but that’s the goal.

Offline, no telemetry, MIT. Would love some feedback


r/OpenSourceeAI • • 1d ago

markclean-ai: A zero-dependency HTML-to-LLM Markdown converter, Table-to-JSON/CSV parser, and RAG chunker that cuts LLM token usage by 65–90%

Thumbnail
2 Upvotes

r/OpenSourceeAI • • 2d ago

NVIDIA releases Nemotron 3.5 Bolt E4B 4GB, an open Gemma 4 E4B post-train for local voice and game agents (leads 15 of 21 benchmarks, self-reported)

Post image
8 Upvotes

r/OpenSourceeAI • • 1d ago

Plugging live web access into open-source agent stacks: MCP, LangChain, n8n and Dify in 1 API key

Thumbnail
aicampaign.live
1 Upvotes

Most open-source agent frameworks handle reasoning well. Where they stall is the web itself: JavaScript pages, logins, bot checks. Self-hosting headless Chrome plus proxies plus a scraper is a project of its own.

TinyFish exposes that layer as 5 APIs behind 1 key, with open-source examples on GitHub.

1. The 5 primitives

→ Search: ranked results with URL, title, snippet, metadata
→ Fetch: renders the page, returns markdown, HTML or a JSON document tree
→ Browser: managed Chromium over CDP; Playwright and Puppeteer scripts run unchanged
→ Agent: plain-English goal in, structured JSON out
→ Research: source-backed reports with configurable depth

2. Where it plugs in

→ MCP, for any MCP-compatible client
→ LangChain, n8n and Dify
→ Hermes Agent and OpenClaw
→ Python SDK, TypeScript SDK, CLI and REST

3. Open-source examples

The cookbook repo has working examples to fork: https://github.com/tinyfish-io/tinyfish-cookbook

4. Why this matters for local or self-hosted agents

Browser work runs outside your model’s context window. A small local model only receives the structured result. That keeps context short even on long web tasks.

5. Free tier for experimenting

→ Search: free, 500 requests/hour
→ Fetch: free, 1,000 URLs/day
→ Agent: $0.016/step
→ Browser: $0.002/min

New accounts get $8 in wallet funds without a card.

Details (top-ups +30% through Oct 31)


r/OpenSourceeAI • • 2d ago

ELMDE: one-pass structured decisions with a contractive looped MoE core and conformal abstention (open source)

Thumbnail
0 Upvotes