asmsense v6 β€” Qwen3-8B LoRA for stripped x86-64 function naming

Repository: krxi123/asmsense-lora-v6. This is a PEFT LoRA adapter, not a standalone 8B base model. It proposes a one-sentence English description, a function name and a Turkish description from the assembly, call context and (when available) anonymized Ghidra pseudocode of one stripped x86-64 function.

Intended use

Local assistance for authorized reverse engineering of stripped x86-64 C binaries: suggest a descriptive function name and summarize what the function might do. The model is an aid, not a replacement for inspecting the disassembly, call graph and decompiler output. Review suggestions before renaming functions or treating a description as evidence. A plausible name is not proof of the original source identifier or of semantic correctness.

The training output is JSON in the order aciklama_en, ad, aciklama. Some rows have a name-only target because teacher descriptions are unavailable. The model can produce malformed or truncated JSON; use the project's output parser rather than assuming every generated string passes json.loads.

Training data and input

v6 retains the v5 selection: 95,000 training rows, 72,061 source functions from 287 projects, with the same row IDs and targets. Training functions come from a permissively licensed open-source C corpus with disjoint root-project identifiers across train/validation/test, not a guarantee of independent source families or absence of vendored copies. Compiled optimization settings are -O0, -O1, -O2, -O3 and -Os. Descriptions are teacher-generated targets based on C source, not human-authored ground truth. Target names come from source symbols, with the project's prefix handling applied.

The v5 assembly + call-context input is retained; v6 appends pseudocode after:

/* --- Ghidra decompile --- */

Project-local symbols are anonymized. Visible imported library names and string literals can remain, as they can in a real binary. A target-name check rejects suspicious pseudocode rather than removing the training/evaluation row. Name anonymization is not a guarantee against every possible leak or pretraining overlap.

Prepared split Rows Rows with pseudocode Tail-truncated pseudocode
train 95,000 94,738 (99.7%) 12,818 (13.5%)
fixed test (test_sabit) 2,000 1,999 (99.95%) 347 (17.35%)
eval115 115 115 (100%) 15 (13.04%)
checkpoint-selection sample (valid_300) 300 299 (99.67%) 26 (8.67%)

The truncation budget is 3,072 tokens for the complete training conversation, not 3,072 pseudocode tokens. Pseudocode is cut from the tail, preserving full lines, and a truncated block that cannot retain the minimum 200-token body is omitted; shorter complete blocks can still be used. Original assembly/context is kept. 80 training pseudocode blocks were excluded by the target-name check; 262 training rows have no usable pseudocode overall. The average full conversation is 1,443 tokens versus 1,037 for v5 (about 1.39Γ—). Input coverage does not change the test row denominator.

Training configuration and checkpoint

Configured pipeline: Qwen3-8B with LoRA rank 16, alpha 32, dropout 0.05, all-linear targets; AdamW learning rate 1e-4, cosine scheduling and warmup ratio 0.03. The conversation is tokenized with thinking disabled. These are the repository settings; the actual completed run is recorded below rather than inferred from defaults.

  • Completed-run configuration (epochs, effective batch, precision, sequence length and any deviations): One epoch over 95,000 rows; 5,938 optimizer steps; bf16, micro batch 2, gradient accumulation 8 (effective batch 16, last batch partial), sequence budget 3,072, seed 7; LoRA rank 16 / alpha 32 / dropout 0.05, 252 all-linear modules; AdamW 1e-4, cosine, warmup 0.03; gradient checkpointing disabled. RTX PRO 6000; original session expired after 12 hours, then exact-source DEVAM restored the step-5,000 adapter plus optimizer/scheduler/RNG/Trainer state. Transformers 5.3.0, PyTorch 2.11.0+cu130; no model, data, package or hyperparameter change.
  • Selection protocol: maximum valid_300 name-token F1 across 12 scheduled checkpoints; selected step 4,500 (0.2680531506); ties retain the earlier checkpoint. Test results were generated only after training ended, not used for checkpoint selection.
  • Evaluated adapter artifact and run evidence: Pinned final HF commit f4d4a0b88ff5321539d4b00f357c9bb5d89a7711; evaluated adapter adim-04500/; durum/son/trainer_state.json records global_step=max_steps=5,938 and epoch=1.0. test_sabit-tamam.json and eval115-tamam.json both match kosu.json/en_iyi.json, with identical SHA-256 cd493e3b00096ad26b645dd92c9123eea0d77e54a7aefbe5aa85be6f21a434ee. The repository also contains adaptor-en-iyi.zip; son/ is the training-last adapter, not the evaluated best adapter.

Use the selected evaluated checkpoint, not an arbitrary intermediate checkpoint or a resume directory. Training completion does not mean the last step is the best validation checkpoint.

Evaluation

Name F1 is the mean per-function token-F1 against the reference name (0–1). Prefix-stripped F1 removes the project's known naming prefix from both reference and prediction. Neither metric is a description-quality measure or a percentage of semantically correct predictions. The historical table's β€œexact” counts are token-set F1=1 counts, not necessarily literal string equality (token ordering/case can differ).

Model Set n Name F1 (-O0 / -O2 / all) Prefix-stripped F1 F1=1 matches (name / prefix-stripped)
Qwen3-8B + LoRA v6 fixed v4 test sample 2000 0.140 / 0.112 / 0.135 0.137 31 / 37
Qwen3-8B + LoRA v6 eval_115 115 0.175 / 0.092 / 0.135 0.153 2 / 3
Qwen3-8B + LoRA v5 (historical) fixed v4 test sample 2,000 0.127 / 0.098 / 0.124 0.126 26 / 31
Qwen3-8B + LoRA v5 (historical) eval_115 115 0.188 / 0.120 / 0.155 0.173 1 / 2

Literal string-exact v6 predictions: 21 on the fixed test and 1 on eval_115; these differ in definition from the table's F1=1 counts.

The paired full-precision v6 βˆ’ v5 name-F1 difference is +0.011 on 2000 fixed-test rows (95% interval +0.002 to +0.018), and -0.020 on 115 eval_115 rows (95% interval -0.057 to +0.020). Interval method/sampling unit: ID-aligned paired project-cluster percentile bootstrap, 2,000 draws, seed 42; resample 26 root-project clusters for the fixed test and five for eval_115 with replacement, keeping all aligned source/optimization rows per sampled project; each draw uses the pooled row-weighted mean v6 βˆ’ v5 difference, not the mean of project means. Interpretation: The fixed-test estimate improves by 0.0111 F1 and its project-cluster interval excludes zero, but eval_115 drops by 0.0201 and its interval spans zero. Neither planned name-F1 target (0.14 / 0.17) was reached. This is not a compute-matched ablation, and the overlapping small benchmark does not independently confirm a gain.

Full decoding, coverage, revision and exclusion protocol: Selected only by the maximum greedy name F1 on valid_300 (300 rows), ties retain the earlier step; no test-guided checkpoint selection or post-result retraining. Final selected-adapter predictions use do_sample=False, enable_thinking=False and max_new_tokens=160. Fixed test: 2,000/2,000 unique aligned IDs; eval_115: 115/115. All generated JSON parsed successfully in both sets; no rows excluded. Both completion stamps match the same run and selected checkpoint. Paired v5 scores are recomputed from ID-aligned full-precision saved predictions.

Planned name-F1 targets were 0.14 (fixed test) and 0.17 (eval_115); both were missed. Fixed-test optimization scores (v5 β†’ v6) were -O0 0.127 β†’ 0.140 (729 rows), -O1 0.133 β†’ 0.150 (470), -O2 0.098 β†’ 0.112 (210), -O3 0.114 β†’ 0.109 (91), and -Os 0.123 β†’ 0.127 (500). The -O3 slice declines; adding pseudocode did not improve every optimization setting.

With complete pseudocode, fixed-test name F1 was 0.125 β†’ 0.139 (1,652 rows); with truncated pseudocode, 0.117 β†’ 0.114 (347); the one missing-pseudocode row stayed at 0.500. On eval_115, complete pseudocode scored 0.140 β†’ 0.135 (100 rows), while truncated pseudocode scored 0.260 β†’ 0.140 (15); no pseudocode-missing rows occur there. These overlapping observational properties are diagnostic, not a randomized estimate of the causal effect of truncation.

Description audit

mimo-v2.6-pro (temperature 0, thinking disabled; source-aware 0/1/2 judgments) compared generated descriptions with the C source on 300 rows from the same 300 fixed-test IDs previously judged for v5, with 300 English and 300 Turkish judgments:

Language Correct Partly correct Wrong
English 21.1% 21.4% 57.5%
Turkish 20.5% 24.7% 54.8%

Audit denominators, failed/missing outputs and v5 comparability: Table percentages use successful decisions: English 62/294 correct (21.1%), 6 unresolved judge failures; Turkish 60/292 correct (20.5%), 8 failures. Failed judgments remain null, are not called wrong, and no sampled ID is removed. On the full 300-ID denominator, English correct is 62/300=20.67% versus v5 59/300=19.67%; paired difference +1.00 percentage point, project-cluster 95% interval βˆ’0.91 to +4.03 points (25 projects, 2,000 draws, seed 42). Turkish is 60/300=20.00% versus v5 62/300=20.67%, difference βˆ’0.67 points (interval βˆ’5.06 to +3.20). Both explanation intervals span zero. The planned 25% English target was missed even if all six unresolved judgments had been correct (68/300=22.67%); the audit is automated, not human-certified. The judge sees C source (first 12,000 characters) and the same teacher reference/prompt as v5, not only the v6 binary input. For context, the historical v5 audit sampled 300 test rows; the English 20.0% correct, 15.3% partial and 64.7% wrong rates use 295 successful judge decisions, with 5 failures (59 correct). Turkish correct was 62/296 (about 20.9%), with 4 failures. Match denominator conventions explicitly when comparing with v6. This is a judge-model assessment, not a human-certified accuracy claim. A validation-set audit and a test-set audit must not be presented as the same comparison.

Limitations and comparison caveats

  • Low name F1 is not solved reverse engineering. There can be many sensible names for a function, yet an apparently fluent description can also be wrong. Do not trust names as security findings or proof of behavior.
  • Pseudocode is incomplete and approximate. Ghidra may infer wrong types or control flow; 13.5% of training rows have tail-truncated pseudocode, with a higher 17.35% on the fixed test sample. The model can miss important statements cut from the tail.
  • v5 is not a compute-matched ablation. Row IDs and targets are preserved, but the input, system prompt and processed token count change. Differences can also depend on checkpoint selection and decoding. Paired intervals must use matched full-precision predictions, not the rounded historical table.
  • Checkpoint-selection bias matters. Validation choices and any repeated/test-guided decisions must be disclosed. An interval spanning zero does not support a reliable improvement claim. eval_115 is small and has five projects; check row/source-function overlap with the fixed test sample before calling it an independent replication.
  • Distribution is narrow. Filtered open-source x86-64 C functions do not represent packed/obfuscated programs, malware, proprietary production binaries, all compilers, other languages or other architectures.
  • Source-aware teacher labels are imperfect. They were produced from source code, while this model only receives binary-derived input. Automatic anonymization and project-level splitting reduce obvious contamination but do not prove that the base model never saw a source project.
  • Anonymization is not target-name-leakage-free. A full-input, case-sensitive whole-token audit found the target text in 5,803/95,000 training rows (6.11%); this is a lexical-match rate, not a verified disclosure rate for all matches. Concrete assertion/logger string disclosures remain because the name check masks string literals. In the fixed test, the two matches out of 2,000 are the add mnemonic rather than exposed source names; eval_115 has zero such matches. These narrow checks do not certify the test inputs as free from all leakage. Nine training rows counted as pseudocode-present contain only Ghidra warning comments and the truncation marker.
  • The small benchmarks overlap. Project/source/function keys place 36 of eval_115's 95 unique source functions in the fixed test sample; its 115 rows include 20 two-optimization variants. It is not an independent replication. Project-disjoint train/validation/test roots do not establish independence of vendored code.
  • Content overlap was audited, but not its performance effect. Across all six prepared files, training has no exact full-user-input match with another split; conservative anonymous-symbol/whitespace normalization finds one full-input match with the full test and none with the fixed sample. However, 47 fixed-test rows match a training pseudocode fragment after normalization, including generic stubs/wrappers that do not prove identical source. Existing source-extraction sidecars contain 45 exact-text groups linking 54 fixed-test rows (45 unique source-function keys) to training; those stored extractions were not revalidated against the v6 binary/source revisions. Neither absence of full-input equality nor presence of these fragment/sidecar matches establishes a contamination rate or a model-score effect.
  • Audit normalization definitions differ. The tracked audit reports 51 normalized-pseudocode matches with a different normalization; that count is not interchangeable with the 47-row conservative census above.
  • The earlier large-model experiment is not a v6 result. Its 0.192 F1 (mimo-v2.6-pro, combined input) motivated adding pseudocode; it does not establish the performance of this adapter.

Local inference

Install torch, transformers, peft, accelerate and sentencepiece in a suitable local environment. The example below reads the prepared, anonymized v6 input, discards the reference assistant response and runs inference only. Extract the veri-v6.zip release and set V6_DATA to the directory containing eval115.jsonl (the release may use a flat archive layout). The base weights and adapter must be downloaded separately; the code is not a training command.

import json
import os
from pathlib import Path

import torch
from peft import PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizer

base = "Qwen/Qwen3-8B"
base_revision = "b968826d9c46dd6066d109eabc6255188de91218"
adapter_revision = "f4d4a0b88ff5321539d4b00f357c9bb5d89a7711"
selected_step = 4500
tokenizer = AutoTokenizer.from_pretrained(base, revision=base_revision)
model = AutoModelForCausalLM.from_pretrained(
    base, revision=base_revision, torch_dtype=torch.bfloat16,
    attn_implementation="sdpa", device_map="auto",
)
model = PeftModel.from_pretrained(
    model, "krxi123/asmsense-lora-v6", revision=adapter_revision,
    subfolder=f"adim-{selected_step:05d}",
)
model.eval()

with (Path(os.environ["V6_DATA"]) / "eval115.jsonl").open(encoding="utf-8") as f:
    row = json.loads(next(f))
messages = row["messages"][:-1]  # remove the reference answer; never give it to the model
prompt = tokenizer.apply_chat_template(
    messages, tokenize=False, add_generation_prompt=True, enable_thinking=False
)
inputs = tokenizer(prompt, add_special_tokens=False, return_tensors="pt").to(
    model.get_input_embeddings().weight.device
)
with torch.inference_mode():
    output = model.generate(
        **inputs, do_sample=False, max_new_tokens=160, use_cache=True,
        pad_token_id=tokenizer.pad_token_id,
    )
print(tokenizer.decode(output[0, inputs["input_ids"].shape[1]:], skip_special_tokens=True))

For a new binary, produce anonymized assembly/context and pseudocode using the project's extraction pipeline and keep the v6 system/input format. Feeding raw decompiler text with real internal names is not equivalent to the evaluation input. Greedy generation with thinking disabled is the repository's evaluation convention; consult the protocol above for the actual measured run. No CPU/GPU memory or latency claim is made here without a measured deployment report.

Licenses and provenance

The adapter's declared release license is apache-2.0; license text: https://huggingface.co/krxi123/asmsense-lora-v6/blob/main/LICENSE. Check the base model's own license and model card as well. Do not interpret the adapter metadata as relicensing the training data.

Pipeline code is MIT. Assembly and Ghidra-derived pseudocode remain derived from the original projects and retain their corresponding permissive licenses and notices (MIT, BSD, ISC, zlib/libpng, Apache-2.0 or public domain, with permissive options selected for dual-licensed projects). Decompiling with Ghidra does not turn the mixed corpus into a single MIT/Apache-2.0 dataset. When redistributing examples, preserve the source project's lisans metadata, attribution and applicable notices; consult veri/LISANSLAR.md, license texts and the scaled corpus's source/license inventory.

Citation

@misc{asmsense_v6_2026,
  title = {asmsense v6: Function Naming with Assembly and Ghidra Pseudocode},
  author = {krxi},
  year = {2026},
  url = {https://github.com/krxi/asmsense}
}
Downloads last month
-
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Model tree for krxi123/asmsense-lora-v6

Finetuned
Qwen/Qwen3-8B
Adapter
(2275)
this model

Dataset used to train krxi123/asmsense-lora-v6