pegasus-0.5-7b

uncc's own matching-decompilation model. Given one function's target assembly and its toolchain, it writes C meant to recompile to the identical bytes (relocations masked), not just to behave the same.

  • base: Qwen/Qwen2.5-Coder-7B-Instruct, LoRA SFT (r 64, alpha 128, 2 epochs, seq 8192), merged to bf16
  • the LoRA adapter alone is in adapter/
  • rung r0: x86 (i386), gcc 15.2 -O2, open-source C
  • site: uncc.sh ยท data: uncc.sh/dataset

Data

2,755 training pairs. Every pair is a function an uncc agent matched byte for byte on r0 targets (doom, zlib, quake, duke3d, quake2): the server recompiled the agent's C with the pinned toolchain and got sha1: OK. Agent claims are never trusted; only the server's re-check admits a pair. The targets' original source was never given to the agents. Splits are by function (stable hash); the test set additionally holds out whole translation units, and identical asm is deduplicated before splitting.

The full, growing pair set is public: uncc.sh/api/dataset/pairs.jsonl.

Eval

Every answer is compiled and diffed by the uncc engine with the same toolchain. Same prompt for every model; the harness prepends the translation unit's #include lines to any answer without one, for every model alike.

  • held-out: 234 r0 functions never seen in training
  • unseen programs: lua 5.4 (200 fns) + brogue CE (200 fns), not in training at all

byte-exact on the first try (greedy):

model params held-out unseen
pegasus-0.5 7B 23.1% 6.3%
Qwen2.5-Coder-32B-Instruct 32B 9.0% 4.3%
Qwen3-Coder-30B-A3B-Instruct 30B MoE 7.7% 3.5%
DeepSeek-Coder-V2-Lite-Instruct 16B MoE 6.0% 2.3%
Qwen2.5-Coder-7B-Instruct (base) 7B 5.1% 2.5%

byte-exact within 9 tries (greedy + 8 samples), every try checked by the compiler:

model held-out unseen
pegasus-0.5 28.2% 8.3%
Qwen2.5-Coder-32B-Instruct 16.2% 7.0%
Qwen3-Coder-30B-A3B-Instruct 9.4% 5.5%
DeepSeek-Coder-V2-Lite-Instruct 7.7% 4.5%
Qwen2.5-Coder-7B-Instruct (base) 6.4% 5.0%

On programs it never saw the gain is small. That is what the next rungs and the next pegasus are for.

Use

The prompt format matters. prompt.py here is the exact template used in training (uncc-chat-v2):

from transformers import AutoTokenizer, AutoModelForCausalLM
from prompt import build_messages, extract_c

tok = AutoTokenizer.from_pretrained("uncc-sh/pegasus-0.5-7b")
model = AutoModelForCausalLM.from_pretrained("uncc-sh/pegasus-0.5-7b", torch_dtype="auto", device_map="auto")

pair = {"symbol": "...", "size": 0, "asm": "...", "toolchain": "gcc-i686-o2", "compiler": "gcc 15.2",
        "flags": "-O2 -march=i686 ...", "arch": "i386"}   # one row of pairs.jsonl, minus "c"
msgs = build_messages(pair, with_answer=False)
inputs = tok.apply_chat_template(msgs, add_generation_prompt=True, return_tensors="pt", return_dict=True).to(model.device)
out = model.generate(**inputs, max_new_tokens=2048, do_sample=False)
print(extract_c(tok.decode(out[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True)))

A match only counts when the C compiles with the target's exact compiler and flags to the same bytes. Check it.

Ladder

r0 = gcc on open C (this model) โ†’ r1 = IDO ยท PsyQ ยท Borland (pegasus-1) โ†’ r2 = MSVC 5/6 โ†’ r3 = MWCC ยท ee-gcc ยท MSVC 7โ€“9 โ†’ r4 = MSVC 14+, x64, LTO. Each rung's verified pairs train the next pegasus.

Licences of the r0 targets differ (GPL-2.0 for the id games and duke3d, zlib licence for zlib); check them before redistributing derived C.

Downloads last month
37
Safetensors
Model size
8B params
Tensor type
BF16
ยท
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ 1 Ask for provider support

Model tree for uncc-sh/pegasus-0.5-7b

Base model

Qwen/Qwen2.5-7B
Finetuned
(491)
this model