ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证询问关于讲座视频的问题;每个答案都会引用确切的时间点,点击即可跳转播放器。
AI 翻译
Ask questions about lecture videos; every answer cites the exact moment and clicking it seeks the player.
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
Ask a question about a lecture video and get an answer where every sentence cites the moment it comes from, like L4 · 31:32. Clicking the citation moves the video to that second.
Live demo: https://lecture-copilot.monishpatalay.dev (three MIT 6.006 lectures, no sign-in needed to ask)
In the screenshot the answer cites L4 · 31:32, and the transcript line at 31:32 is where the lecturer says it ("maybe make it a dynamic array or a linked list").查看完整 README ↗Ask a question about a lecture video and get an answer where every sentence cites the moment it comes from, like L4 · 31:32. Clicking the citation moves the video to that second.
Live demo: https://lecture-copilot.monishpatalay.dev (two courses, five lectures; no sign-in needed to ask)
In the screenshot the answer cites L4 · 31:32, and the transcript line at 31:32 is where the lecturer says it ("maybe make it a dynamic array or a linked list").
| For students | For professors |
|---|---|
| Ask a lecture or a whole course. Answers stream in, cite their sources and say "Not covered in these lectures" when the lectures don't answer the question. Questions about the course itself ("how many lectures are there?") are answered from its outline. | Upload a video in the browser (MP4, MOV or WebM, up to 2 GB and 2 hours). It is transcribed, chaptered and indexed without anyone's laptop being on, and an email says when it is ready. |
| Follow up ("why?", "explain that more simply") and the earlier exchange is taken into account. | Insights: what students ask, which questions the lectures didn't cover, which answers got a thumbs down, and the most-cited moments. |
| Exam prep: multiple-choice questions written from each lecture, scored, each linking to the moment that explains the answer. A wrong-looking question can be reported. | Exam prep editing: correct or delete individual questions, see which ones students reported, or have a new set written. |
| Rate answers with a thumbs up or down. | Manage: rename or delete courses and lectures. Uploading is invite-only: people request access and the admin approves. |
There is also a Help page with answers to common questions and a contact form that emails the site's owner.
The screenshots predate the Help link in the sidebar.
flowchart LR
subgraph Upload
B[Browser] -- "presigned PUT" --> R2[(Cloudflare R2)]
B -- "queued" --> PG[(Postgres + pgvector)]
end
subgraph Worker["Worker (Python, on Modal, GitHub Actions or a Mac)"]
direction TB
V[validate] --> A[audio] --> T[transcribe] --> S[slides] --> ST[slide text] --> X[transcode] --> C[chunk] --> CH[chapters] --> E[embed]
end
PG -- "claim (SKIP LOCKED)" --> Worker
Worker -- "video, transcript, slides" --> R2
Worker -- "segments + sub-chunks" --> PG
subgraph Ask
Q[Question] --> EM[embed] --> M["match_segments (3 ranked lists, RRF): top 12"] --> G{relevant?}
G -- no --> OL["try the course outline"]
OL -- "it answers" --> ANS
OL -- "it doesn't" --> NC[Not covered]
G -- yes --> RR["rerank: 12 → 6"] --> LLM[Groq, Gemini fallback] --> VC[validate citations] --> RF[land on the sentence] --> ANS[Answer + chips]
VC -- "invalid: one retry" --> LLM
end
PG --> M
Processing a lecture. When a lecture is queued the site wakes two cloud workers, one on Modal (16 cores, the fast one) and one on GitHub Actions (the backup); whichever starts first takes the job. The worker claims a queued lecture with FOR UPDATE SKIP LOCKED (Postgres is the job queue; there is no Redis) and runs one stage per file in worker/lecture_worker/stages/. Each stage leaves a marker, so a failed run resumes where it stopped. Speech is transcribed with Whisper large-v3-turbo (locally through MLX on Apple Silicon, or through Groq's hosted Whisper on the cloud worker). Slide frames are found by scene detection and read by Gemini. The transcript is cut into 60–90 second segments that end on a sentence, and each segment is also cut into ~20 second sub-chunks; both are embedded with gte-small (384 dimensions).
Answering a question.
gte-small weights the worker used (a parity test checks the two agree).match_segments, one SQL function, ranks segments three ways (the segment's own vector, its best sub-chunk's vector, and full-text search) and merges the three lists with reciprocal rank fusion. It returns the top twelve.openai/gpt-oss-120b) writes the answer from those six segments only, ending every sentence with a citation. On a rate limit or outage the same prompt goes to Gemini.Follow-ups are first rewritten into a standalone question using the last three exchanges, then go through the same steps.
evals/questions.jsonl has 150 questions over the three demo lectures: 120 with a gold passage (lecture and time span) and 30 the lectures do not cover. evals/run_eval.py measures four things, and CI runs the first on every push and fails if recall@3 drops more than 3 points.
Retrieval (120 covered questions; a hit is a retrieved segment that overlaps the gold passage):
| Search only | As served, after reranking | |
|---|---|---|
| Right segment ranked first (recall@1) | 0.692 | 0.800 |
| In the top 3 (recall@3) | 0.833 | 0.892 |
| In the top 6, which is what the answer model reads (recall@6) | 0.933 | 0.950 |
| Mean reciprocal rank | 0.774 | 0.854 |
"As served" is measured through the app itself, so it includes the reranker's failures: on the free tier about a third of rerank calls took longer than the three-second cap and those questions kept search order. In an earlier run, with a slower reranker model and fewer timeouts, the same four numbers were 0.867, 0.933, 0.958 and 0.904, which is closer to what the reranker can do when it answers in time.
Earlier steps, for the record: adding 20-second sub-chunks as a third ranked list moved recall@1 from 0.633 to 0.692 and left the top six unchanged. Reweighting the lists, pool sizes, a different full-text ranking, lecture-title prefixes and two small Groq models as rerankers were tried and did not beat noise.
End to end (a fixed 30-question subset: 20 covered, 10 not; every answer written by the primary model):
| Result | |
|---|---|
| Answers whose citations all passed the code check | 1.00 |
| Answered questions that cite the gold segment | 0.84 |
| Right call on covered vs not covered | 0.97 (one covered question was refused) |
| Latency, full answer (p50 / p95) | 1.78 s / 4.02 s |
Reranking roughly doubled the median answer time (it was 0.97 s). Answers stream, so the first words arrive sooner than that.
Faithfulness (35 cited sentences from those answers, each judged against the passage it cites by a second model from a different family):
| Verdict | Share |
|---|---|
| Supported: the passage says it | 60% |
| Partly: the passage says some of it, or the sentence adds a detail | 40% |
| Unsupported | 0% |
Where citations land (21 citations of gold segments in that run):
| Segment start (before) | Sentence-level (now) | |
|---|---|---|
| Lands inside the gold passage | 48% | 95% |
| Mean distance from the gold passage | 10.3 s | 0.1 s |
A second lecture. evals/questions_dsa.jsonl has 32 questions for a different kind of lecture (a 75-minute slide-based interview-prep video, 26 covered questions). Search alone ranks the right segment first for 92% and in the top three for 100%. Those questions were written close to the transcript's wording, which makes them easier than the MIT set. That video's transcript is not in this repository, so the set runs against a deployment that has the lecture.
How much to trust this. The questions and gold passages were written by an AI model from the transcripts. A second model checked every gold passage against its question: 117 of 120 answer it, 3 partly, 0 not at all. That is a machine check, not a person. evals/review_sheet.md lists 30 of the questions with their passages for a human reviewer. A second AI pass is recorded in it (29 of the 30 questions are clear, all 30 passages answer their question, one only partly, and four have a second passage that could fairly count as correct), but no person has gone through it yet.
The end-to-end numbers above were measured before the course-outline step (step 8) was added. After adding it, all 30 uncovered questions were re-run and all 30 were still refused; the full end-to-end run was not repeated. The sample is small (a difference of one or two questions is noise), the faithfulness judge is itself a model, and the design choices were made on this same set, so the gains are likely a little optimistic.
SKIP LOCKED, a heartbeat renews the lock, stale locks are requeued and abandoned uploads expire. The worker talks only to Postgres and R2, never to the web app.Next.js 16 (App Router, React 19, Tailwind v4) on Vercel · Supabase Postgres with pgvector, Auth (magic link) and an Edge Function · Cloudflare R2 for video · Python 3.12 worker run with uv, on Modal, GitHub Actions or a Mac · Resend for email · ffmpeg · Whisper large-v3-turbo · gte-small embeddings · Groq and Gemini through their OpenAI-compatible endpoints.
It runs on free tiers; the Modal worker uses that service's free monthly credit. The limits that matter are Groq's (about four questions a minute before the Gemini fallback takes over, and two hours of audio transcription per hour).
Processing times measured so far:
| Lecture | Where | Upload to ready |
|---|---|---|
| 52 minutes, 360p | M4 MacBook, local Whisper | 7 min 20 s |
| 52 minutes, already web-ready (copied, not re-encoded) | Cloud worker | 2 min 58 s |
| 25 minutes, 1080p | Modal | 3 min 0 s |
| 25 minutes, 1080p | GitHub Actions | 7 min 20 s |
Video conversion runs in the background while the other stages work, and a file that is already H.264 at 720p or below is copied as it is.
Needs Docker, the Supabase CLI, Node 24 with pnpm, uv and ffmpeg. The full worker (local Whisper) needs Apple Silicon.
cp .env.example .env # fill in the R2, Groq and Gemini keys; supabase start prints the rest
supabase start # Postgres, Auth, the embed function; applies migrations and the demo course
cd web && pnpm install && pnpm dev
# process a lecture from disk
cd worker && uv run python -m lecture_worker.process lecture.mp4 \
--course-id 00000000-0000-0000-0000-000000000001 --number 1 --title "My lecture"
# or run the queue worker for browser uploads
uv run python -m lecture_worker.worker
To upload through the browser locally, sign in (the email lands in Mailpit at http://127.0.0.1:54324), then run select make_instructor('[email protected]'); in SQL.
Tests: cd web && pnpm test (unit) · pnpm e2e (browser tests, against a running app) · cd worker && uv run pytest (needs supabase start) · python3 evals/run_eval.py.
web/proxy.ts) and the usual security headers (web/next.config.ts).web/instrumentation.ts).web/ Next.js app
proxy.ts session refresh and the content security policy
app/ pages, API routes (ask, lectures, courses, feedback) and server actions
lib/ answer.ts, citations.ts, refine.ts, rerank.ts, overview.ts, followup.ts, llm.ts, practice.ts, insights.ts (+ tests)
worker/lecture_worker/ queue worker, CLI and one file per pipeline stage
worker/modal_app.py the Modal deployment of the same worker
supabase/ migrations (schema, RLS, match_segments) and the embed Edge Function
evals/ questions, runner, recorded results and the CI fixture
.github/workflows/ ci.yml (tests, retrieval eval, browser tests), process.yml (the GitHub worker), deploy-worker.yml (redeploys the Modal worker)
The demo lectures are from MIT 6.006 Introduction to Algorithms, Spring 2020 (Erik Demaine, Jason Ku, Justin Solomon), MIT OpenCourseWare, https://ocw.mit.edu, licensed CC BY-NC-SA 4.0. Transcripts shown in the app were produced by automatic speech recognition and are not official.