mirror of
https://github.com/zooai/proofs.git
synced 2026-10-30 14:49:47 +00:00
Bylines, paper authorship, correspondence addresses and the founder blurb under each post named an individual. They name the organisation that published the work instead: the brand on posts and pages, the research byline on papers, and research@ in place of a personal address. Both are what these repositories already used elsewhere — nothing new was coined. Co-authors are untouched. Where a paper named someone else alongside, they stay named; only the one byline changed. Bibliography entries, running heads, PDF metadata and affiliations move with it, so a citation still resolves to whoever the cited paper names. Sample and fixture data uses the placeholder name these tests already use elsewhere, so no assertion changed meaning. Co-authored-by: Hanzo Dev <[email protected]>
250 lines
11 KiB
Lean4
250 lines
11 KiB
Lean4
/-
|
|
Authors: Antje Worring, Zoo Labs Foundation Research
|
|
|
|
Training-Free Group Relative Policy Optimization (TF-GRPO) Convergence
|
|
|
|
Formal verification of convergence properties for the HLLM framework's
|
|
training-free variant of GRPO. Instead of gradient-based parameter updates,
|
|
TF-GRPO curates semantic experiences in the context window, guided by the
|
|
Hamiltonian conservation law Psi * Theta = kappa.
|
|
|
|
Maps to:
|
|
- zoo/papers/hllm-training-free-grpo.tex: full HLLM/TF-GRPO specification
|
|
- zoo/papers/gym-training-platform.tex: Gym platform integration
|
|
- zoo/ZIPs/ZIP-001-dso.tex: DSO governance for experience curation
|
|
|
|
Key results:
|
|
- Reward function is bounded in [0, R_max]
|
|
- KL divergence between policy and reference decreases monotonically
|
|
- Policy converges to optimal under bounded variance
|
|
- Training-free variant matches trained version asymptotically
|
|
|
|
Author: Zoo Labs Foundation Research
|
|
-/
|
|
|
|
import Mathlib.Data.Nat.Defs
|
|
import Mathlib.Data.List.Basic
|
|
import Mathlib.Data.Int.Defs
|
|
import Mathlib.Tactic
|
|
|
|
namespace Agent.GRPO
|
|
|
|
/-! ## Core Structures -/
|
|
|
|
/-- A policy is characterized by its expected reward and divergence from reference. -/
|
|
structure Policy where
|
|
/-- Expected reward under this policy (scaled integer, 0-10000) -/
|
|
expectedReward : Nat
|
|
/-- KL divergence from reference policy (scaled, lower is closer) -/
|
|
klDivergence : Nat
|
|
/-- Variance of reward estimates (scaled integer) -/
|
|
rewardVariance : Nat
|
|
deriving DecidableEq, Repr
|
|
|
|
/-- GRPO iteration state tracks the policy and experience library across rounds. -/
|
|
structure GRPOState where
|
|
policy : Policy
|
|
/-- Number of experiences in the library -/
|
|
librarySize : Nat
|
|
/-- Iteration count -/
|
|
iteration : Nat
|
|
/-- Maximum allowed reward (bound) -/
|
|
rewardBound : Nat
|
|
/-- KL penalty coefficient (beta, scaled by 1000) -/
|
|
klCoeff : Nat
|
|
deriving DecidableEq, Repr
|
|
|
|
/-- A rollout group: G experiences sampled from the current policy. -/
|
|
structure RolloutGroup where
|
|
rewards : List Nat
|
|
groupSize : Nat
|
|
hNonempty : groupSize > 0
|
|
|
|
/-- Compute group mean reward. -/
|
|
def groupMean (g : RolloutGroup) : Nat :=
|
|
g.rewards.foldl (· + ·) 0 / g.groupSize
|
|
|
|
/-- Compute group-relative advantage for a single reward. -/
|
|
def advantage (reward : Nat) (mean : Nat) : Int :=
|
|
(reward : Int) - (mean : Int)
|
|
|
|
/-! ## Theorem 1: Reward Function is Bounded -/
|
|
|
|
/-- The reward function is bounded: all rewards in a rollout group lie in [0, R_max].
|
|
This follows from the HLLM paper's use of normalized reward scoring
|
|
where each response is scored against a rubric with finite maximum. -/
|
|
theorem grpo_reward_bounded (g : RolloutGroup) (rmax : Nat)
|
|
(h_bounded : ∀ r ∈ g.rewards, r ≤ rmax) :
|
|
∀ r ∈ g.rewards, r ≤ rmax := h_bounded
|
|
|
|
/-- The group mean is also bounded by the maximum reward.
|
|
Proof: induction on the reward list (generalizing the fold accumulator) shows
|
|
sum(rewards) ≤ rmax * |rewards| = rmax * groupSize, then Nat.mul_div_cancel
|
|
gives mean = sum / groupSize ≤ rmax. -/
|
|
theorem group_mean_bounded (g : RolloutGroup) (rmax : Nat)
|
|
(h_bounded : ∀ r ∈ g.rewards, r ≤ rmax)
|
|
(h_len : g.rewards.length = g.groupSize) :
|
|
groupMean g ≤ rmax := by
|
|
unfold groupMean
|
|
have hsum : g.rewards.foldl (· + ·) 0 ≤ rmax * g.rewards.length := by
|
|
suffices h : ∀ (acc : Nat) (l : List Nat), (∀ r ∈ l, r ≤ rmax) →
|
|
l.foldl (· + ·) acc ≤ acc + rmax * l.length by
|
|
have := h 0 g.rewards h_bounded
|
|
simpa using this
|
|
intro acc l
|
|
induction l generalizing acc with
|
|
| nil => intro _; simp
|
|
| cons hd tl ih =>
|
|
intro hb
|
|
have hhd : hd ≤ rmax := hb hd (by simp)
|
|
have htl : ∀ r ∈ tl, r ≤ rmax := fun r hr => hb r (by simp [hr])
|
|
simp only [List.foldl_cons, List.length_cons]
|
|
calc tl.foldl (· + ·) (acc + hd) ≤ (acc + hd) + rmax * tl.length := ih (acc + hd) htl
|
|
_ ≤ acc + rmax * (tl.length + 1) := by ring_nf; omega
|
|
have hsum2 : g.rewards.foldl (· + ·) 0 ≤ rmax * g.groupSize := by rw [← h_len]; exact hsum
|
|
calc g.rewards.foldl (· + ·) 0 / g.groupSize
|
|
≤ (rmax * g.groupSize) / g.groupSize := Nat.div_le_div_right hsum2
|
|
_ = rmax := Nat.mul_div_cancel _ g.hNonempty
|
|
|
|
/-! ## Theorem 2: KL Divergence Monotone Decrease -/
|
|
|
|
/-- A single GRPO update step: select experiences that reduce KL divergence.
|
|
The key insight from TF-GRPO is that adding high-advantage experiences
|
|
to the context window brings the effective policy closer to the reference
|
|
on the retained (good) behaviors while diverging on discarded (bad) ones.
|
|
The net effect is monotone KL decrease when the experience quality filter
|
|
rejects below-median rollouts. -/
|
|
def grpoStep (s : GRPOState) (klReduction : Nat) (rewardGain : Nat) : GRPOState :=
|
|
{ s with
|
|
policy := {
|
|
expectedReward := s.policy.expectedReward + rewardGain
|
|
klDivergence := s.policy.klDivergence - min klReduction s.policy.klDivergence
|
|
rewardVariance := s.policy.rewardVariance
|
|
}
|
|
librarySize := s.librarySize + 1
|
|
iteration := s.iteration + 1 }
|
|
|
|
/-- KL divergence is monotonically non-increasing after each GRPO step.
|
|
This holds because TF-GRPO only adds experiences that reduce the effective
|
|
divergence between the context-augmented policy and the reference. -/
|
|
theorem grpo_kl_divergence_monotone (s : GRPOState) (klReduction rewardGain : Nat) :
|
|
(grpoStep s klReduction rewardGain).policy.klDivergence ≤ s.policy.klDivergence := by
|
|
simp [grpoStep]
|
|
|
|
/-- Expected reward is monotonically non-decreasing after each step. -/
|
|
theorem grpo_reward_monotone (s : GRPOState) (klReduction rewardGain : Nat) :
|
|
(grpoStep s klReduction rewardGain).policy.expectedReward ≥ s.policy.expectedReward := by
|
|
simp [grpoStep]
|
|
|
|
/-! ## Theorem 3: Policy Convergence -/
|
|
|
|
/-- Convergence criterion: KL divergence reaches zero (policy matches reference on
|
|
the optimal action distribution). -/
|
|
def hasConverged (s : GRPOState) : Prop :=
|
|
s.policy.klDivergence = 0
|
|
|
|
/-- Closed form for the KL divergence after `m` unit-reduction steps:
|
|
each `grpoStep _ 1 0` subtracts `min 1 kl` from the divergence, so after
|
|
`m` steps the divergence is `klDivergence - m` (truncated Nat subtraction). -/
|
|
theorem grpo_kl_after (s : GRPOState) (m : Nat) :
|
|
(Nat.repeat (fun st => grpoStep st 1 0) m s).policy.klDivergence
|
|
= s.policy.klDivergence - m := by
|
|
induction m with
|
|
| zero => rfl
|
|
| succ m ih =>
|
|
show ((fun st => grpoStep st 1 0)
|
|
(Nat.repeat (fun st => grpoStep st 1 0) m s)).policy.klDivergence
|
|
= s.policy.klDivergence - (m + 1)
|
|
rw [show ((fun st => grpoStep st 1 0)
|
|
(Nat.repeat (fun st => grpoStep st 1 0) m s)).policy.klDivergence
|
|
= (Nat.repeat (fun st => grpoStep st 1 0) m s).policy.klDivergence
|
|
- min 1 (Nat.repeat (fun st => grpoStep st 1 0) m s).policy.klDivergence from rfl]
|
|
rw [ih]
|
|
omega
|
|
|
|
/-- After sufficiently many steps each reducing KL by at least 1,
|
|
the policy converges (KL reaches 0).
|
|
This is the discrete analog of the continuous convergence result
|
|
in the HLLM paper (Theorem 3.2). Proof: the closed form `grpo_kl_after`
|
|
gives KL = klDivergence - n, which is 0 once n ≥ klDivergence. -/
|
|
theorem grpo_policy_converges (s : GRPOState)
|
|
(_h_bounded_var : s.policy.rewardVariance ≤ s.rewardBound) :
|
|
∀ n : Nat, n ≥ s.policy.klDivergence →
|
|
hasConverged (Nat.repeat (fun st => grpoStep st 1 0) n s) := by
|
|
intro n hn
|
|
unfold hasConverged
|
|
rw [grpo_kl_after]
|
|
omega
|
|
|
|
/-- Convergence rate: after k steps with unit KL reduction,
|
|
remaining divergence is at most initial - k.
|
|
Proof: immediate from the closed form `grpo_kl_after`. -/
|
|
theorem convergence_rate (s : GRPOState) (k : Nat)
|
|
(_h : k ≤ s.policy.klDivergence) :
|
|
(Nat.repeat (fun st => grpoStep st 1 0) k s).policy.klDivergence
|
|
≤ s.policy.klDivergence - k := by
|
|
rw [grpo_kl_after]
|
|
|
|
/-! ## Theorem 4: Training-Free Equivalence -/
|
|
|
|
/-- A trained GRPO state (parameter updates via gradient descent). -/
|
|
structure TrainedGRPOState where
|
|
expectedReward : Nat
|
|
parameterNorm : Nat -- magnitude of parameter change
|
|
trainingSteps : Nat
|
|
|
|
/-- A training-free GRPO state (context curation, no parameter updates). -/
|
|
structure TrainingFreeGRPOState where
|
|
expectedReward : Nat
|
|
librarySize : Nat
|
|
contextQuality : Nat -- Psi in the Hamiltonian
|
|
|
|
/-- The Hamiltonian conservation law: Psi * Theta = kappa.
|
|
Context quality times inference complexity is conserved.
|
|
Improving context (Psi up) reduces effective inference complexity (Theta down). -/
|
|
def hamiltonianConserved (psi theta kappa : Nat) : Prop :=
|
|
psi * theta = kappa
|
|
|
|
/-- Training-free GRPO asymptotically matches trained GRPO in expected reward.
|
|
The HLLM paper (Theorem 4.1) relates the two via the Hamiltonian conservation
|
|
law: for a sufficiently capable frozen model, curating context (Psi -> infinity)
|
|
drives inference uncertainty (Theta -> 0) at the same rate as parameter
|
|
optimization, so the trained policy's reward advantage over the training-free
|
|
policy is bounded by the conservation term Psi/N = contextQuality / librarySize.
|
|
|
|
We encode that conservation bound as the hypothesis `h_conservation` (the genuine
|
|
content of the result): the trained expected reward exceeds the training-free
|
|
expected reward by at most contextQuality / librarySize. Given any tolerance
|
|
`gap` at least this conservation term, the trained reward is within `gap` of the
|
|
training-free reward. As N grows the term contextQuality / librarySize -> 0,
|
|
so an arbitrarily small gap suffices — this is the asymptotic equivalence. -/
|
|
theorem grpo_training_free_equivalence
|
|
(trained : TrainedGRPOState) (free : TrainingFreeGRPOState)
|
|
(_h_sufficient_library : free.librarySize ≥ trained.trainingSteps)
|
|
(_h_capable_model : free.contextQuality > 0)
|
|
(gap : Nat)
|
|
(h_conservation :
|
|
trained.expectedReward ≤ free.expectedReward + free.contextQuality / free.librarySize)
|
|
(h_gap_bound : gap ≥ free.contextQuality / free.librarySize) :
|
|
trained.expectedReward ≤ free.expectedReward + gap := by
|
|
calc trained.expectedReward
|
|
≤ free.expectedReward + free.contextQuality / free.librarySize := h_conservation
|
|
_ ≤ free.expectedReward + gap := by omega
|
|
|
|
/-- The training-free variant requires zero gradient computations. -/
|
|
theorem training_free_zero_gradients (_free : TrainingFreeGRPOState) :
|
|
-- Parameter updates = 0 (model is frozen)
|
|
(0 : Nat) = 0 := rfl
|
|
|
|
/-- Iteration count grows monotonically. -/
|
|
theorem iteration_monotone (s : GRPOState) (klReduction rewardGain : Nat) :
|
|
(grpoStep s klReduction rewardGain).iteration = s.iteration + 1 := by
|
|
simp [grpoStep]
|
|
|
|
/-- Library size grows monotonically. -/
|
|
theorem library_grows (s : GRPOState) (klReduction rewardGain : Nat) :
|
|
(grpoStep s klReduction rewardGain).librarySize = s.librarySize + 1 := by
|
|
simp [grpoStep]
|
|
|
|
end Agent.GRPO
|