Download engine/backend.py from decisionmodels/REAX-1.3: direct link, hf CLI and curl.
- Browser
- Download file 12.4 kB
-
https://huggingface.co/decisionmodels/REAX-1.3/resolve/main/engine/backend.py
- Command line
-
hf download hf://decisionmodels/REAX-1.3/engine/backend.py
-
curl -L -o backend.py https://huggingface.co/decisionmodels/REAX-1.3/resolve/main/engine/backend.py
12.4 kB
| # SPDX-License-Identifier: MIT | |
| """Native K and U frontends in one isolated process/GPU, changed weight storage only.""" | |
| import os,sys,json,time,threading,traceback,contextlib | |
| from pathlib import Path | |
| assert Path('/.dockerenv').exists() and os.environ.get('DUO_ISOLATED')=='1' | |
| import torch,numpy as np | |
| from autotune_guard import install as install_autotune_guard,pin_answer_configs | |
| install_autotune_guard() | |
| import fast_fp8_gemm | |
| fast_fp8_gemm.install() | |
| import transformers | |
| from concurrent.futures import ThreadPoolExecutor | |
| K_STREAM=None | |
| G_PATH=os.environ['REAX_PART_G'] | |
| Q_PATH=os.environ['REAX_PART_Q'] | |
| from transformers import AutoConfig,AutoTokenizer,AutoModelForCausalLM,AutoModelForImageTextToText,FineGrainedFP8Config,BitsAndBytesConfig | |
| sys.path.insert(0,str(Path(__file__).resolve().parent/'third_party/knowline')) | |
| import knowline_server as ks | |
| from knowline_layout import Layout | |
| mode,scheme="duo","fp8";torch.set_num_threads(4) | |
| def quant(): | |
| if scheme=='bf16':return None | |
| if scheme.startswith('fp8'): | |
| return FineGrainedFP8Config(weight_block_size=(128,128) if scheme=='fp8' else (64,64),modules_to_not_convert=['lm_head','visual','model.visual','vision_tower','model.vision_tower','multi_modal_projector','model.multi_modal_projector','audio_tower','model.audio_tower','embed_vision','model.embed_vision','embed_audio','model.embed_audio','in_proj_a','in_proj_b']) | |
| return BitsAndBytesConfig(load_in_8bit=True,llm_int8_threshold=6.0,llm_int8_skip_modules=['lm_head','visual','model.visual','vision_tower','model.vision_tower','multi_modal_projector','model.multi_modal_projector','audio_tower','model.audio_tower','embed_vision','model.embed_vision','embed_audio','model.embed_audio','in_proj_a','in_proj_b']) | |
| def info(m): | |
| from collections import Counter | |
| return {'classes':dict(Counter(type(x).__name__ for x in m.modules())),'parameter_bytes':sum(p.numel()*p.element_size() for p in m.parameters()),'dtypes':dict(Counter(str(p.dtype) for p in m.parameters()))} | |
| def kload(): | |
| cfg=AutoConfig.from_pretrained(G_PATH);cls=getattr(transformers,'AutoModelForMultimodalLM',AutoModelForImageTextToText) if hasattr(cfg,'vision_config') or hasattr(cfg,'audio_config') else AutoModelForCausalLM | |
| kw={'dtype':torch.bfloat16,'device_map':{'':'cuda:0'},'attn_implementation':'flex_attention','local_files_only':True} | |
| if quant() is not None:kw['quantization_config']=quant() | |
| m=cls.from_pretrained(G_PATH,**kw).eval();tok=AutoTokenizer.from_pretrained(G_PATH) | |
| class Backend: | |
| def warm(self,*a):pass | |
| def score(self,text,media,ids): | |
| if media:raise ValueError('text only') | |
| with torch.inference_mode(): | |
| inputs=torch.tensor([tok.encode(text,add_special_tokens=False)],device='cuda:0') | |
| logits=m(input_ids=inputs,logits_to_keep=1,use_cache=False,kernel_options={'BLOCK_M':32,'BLOCK_N':32}).logits[0,-1].float().log_softmax(-1) | |
| return [float(logits[i]) for i in ids],int(inputs.shape[1]) | |
| temps=json.load(open(Path(G_PATH)/'temperatures.json' if (Path(G_PATH)/'temperatures.json').exists() else Path(__file__).resolve().parent/'third_party/knowline/temperatures.json'));engine=ks.KnowLine(tok,Backend(),1.0,1,temps,Layout(read_twice=True,twice_max_tokens=3000)) | |
| return engine,m | |
| try: | |
| k,km=kload();u=None | |
| tok=AutoTokenizer.from_pretrained(G_PATH);tiny=torch.tensor([tok.encode('Hello',add_special_tokens=False)],device='cuda:0') | |
| with torch.inference_mode(): | |
| one=km(input_ids=tiny,logits_to_keep=1,use_cache=True,kernel_options={'BLOCK_M':32,'BLOCK_N':32}).logits.float() | |
| two=km(input_ids=tiny,logits_to_keep=1,use_cache=False,kernel_options={'BLOCK_M':32,'BLOCK_N':32}).logits.float() | |
| cache_parity=float((one-two).abs().max());assert torch.allclose(one,two,atol=.04,rtol=.04), 'cache-free prefill parity' | |
| del one,two,tiny | |
| if mode=='duo': | |
| sys.path.insert(0,Q_PATH) | |
| import d3_runtime | |
| original=d3_runtime.backbone_class | |
| def backbone(kind): | |
| cls=original(kind) | |
| class QuantizedLoader: | |
| def from_pretrained(*a,**kw): | |
| kw['quantization_config']=quant();kw['local_files_only']=True | |
| return cls.from_pretrained(*a,**kw) | |
| return QuantizedLoader | |
| d3_runtime.backbone_class=backbone | |
| # Same class used by AutoModel's native d3 entrypoint; wrapper delegates system_one directly. | |
| from modeling_d3 import D3Model | |
| u=D3Model.from_pretrained(Q_PATH,device='cuda:0',local_files_only=True,batch_size=1) | |
| original_run=u.runtime._run | |
| def bounded_run(prepared): | |
| wanted=u.runtime.batch_size | |
| longest=max([len(x) for x in prepared.sequences.values()]+[len(x) for x in prepared.reversed_sequences.values()]+[1]) | |
| u.runtime.batch_size=min(wanted,max(1,4096//longest)) | |
| try:return original_run(prepared) | |
| finally:u.runtime.batch_size=wanted | |
| u.runtime._run=bounded_run | |
| pin_answer_configs() | |
| ba_patches=[] | |
| state_once_backend=d3_runtime.StateOnce(u.backbone.language_model) | |
| opt_active='plain' | |
| from transformers.models.qwen3_5 import modeling_qwen3_5 as qwen_modeling | |
| from causal_conv1d import causal_conv1d_fn as official_conv | |
| def optimized_conv(x,weight,bias=None,activation=None,**kw):return official_conv(x,weight,bias,activation=activation) | |
| def reference_conv(x,weight,bias=None,activation=None,**kw): | |
| out=torch.nn.functional.conv1d(x.to(weight.dtype),weight[:,None,:],bias,padding=weight.shape[-1]-1,groups=weight.shape[0])[...,:x.shape[-1]] | |
| return (torch.nn.functional.silu(out) if activation in ['silu','swish'] else out).to(x.dtype) | |
| qwen_modeling.causal_conv1d_fn=reference_conv | |
| cx=torch.randn(1,512,1024,device='cuda',dtype=torch.bfloat16);cw=torch.randn(512,4,device='cuda',dtype=torch.bfloat16) | |
| ca=reference_conv(cx,cw,activation='silu');cb=optimized_conv(cx,cw,activation='silu') | |
| conv_probe={'max_abs':float((ca-cb).abs().max()),'mean_abs':float((ca-cb).abs().mean())} | |
| assert torch.allclose(ca,cb,atol=.08,rtol=.02), 'convolution parity prerequisite' | |
| del cx,cw,ca,cb | |
| if scheme!='bf16': | |
| for model in [km]+([u.backbone] if u else []): | |
| assert any('float8' in str(p.dtype) or p.dtype==torch.int8 for p in model.parameters()), 'quantization silently dequantized' | |
| torch.cuda.synchronize() | |
| fast_fp8_gemm.precompile() | |
| print(json.dumps({'ready':True,'autotuner_guard':True,'mode':mode,'scheme':scheme,'cache_parity_max_abs':cache_parity,'gpu':torch.cuda.get_device_name(0),'k':info(km),'u':info(u.backbone) if u else None,'allocated':torch.cuda.memory_allocated(),'reserved':torch.cuda.memory_reserved(),'peak_load_bytes':torch.cuda.max_memory_allocated()}),flush=True) | |
| except BaseException: | |
| traceback.print_exc();raise | |
| K_DONE=threading.Event() | |
| def invoke_k(r): | |
| try: | |
| a,usage=k.run(r['state'],r['questions']) | |
| if opt_active in ['longcache','fastconv_longcache','fast_all_longcache']:torch.cuda.current_stream().synchronize() | |
| return {'answers':a,'usage':usage} | |
| finally:K_DONE.set() | |
| def invoke_u(r): | |
| u.runtime.fast_route={'state_once':False,'oom_fallback':False,'serialized_for_memory':False} | |
| if opt_active in ['state_once','fastconv_state_once','fast_all','longcache','fastconv_longcache','fast_all_longcache'] and len(r['questions'])>1: | |
| prepared=u.runtime.prepare(r['state'],r['questions']) | |
| prefix=max(list(prepared.states.values())+[0]);long_mode=opt_active in ['longcache','fastconv_longcache','fast_all_longcache'];use=0<prefix<=(24576 if long_mode else 16384) | |
| u.runtime.fast_route.update(prefix_tokens=prefix,state_once=use) | |
| if use and long_mode and prefix>16384: | |
| # General length policy: avoid overlapping peak activations for large native prefix caches. | |
| if not K_DONE.wait(300):raise RuntimeError('K completion wait exceeded memory-scheduling budget') | |
| u.runtime.fast_route['serialized_for_memory']=True | |
| u.runtime.state_once=state_once_backend if use else None | |
| try: | |
| result=None | |
| if use: | |
| try:result=u.runtime.run(prepared) | |
| except torch.OutOfMemoryError:pass | |
| if result is None: | |
| if use: | |
| u.runtime.state_once=None;u.runtime.fast_route.update(state_once=False,oom_fallback=True);torch.cuda.empty_cache() | |
| result=u.runtime.run(prepared) | |
| probabilities,tokens=result | |
| return u.runtime.respond(prepared,probabilities,tokens) | |
| finally:u.runtime.state_once=None | |
| return u.system_one(state=r['state'],questions=r['questions']) | |
| from probabilities import mix | |
| norm_patches=[] | |
| for mod_name,mod in km.named_modules(): | |
| if type(mod).__name__.endswith('RMSNorm'): | |
| norm_patches.append((mod,mod.forward,None)) | |
| def apply_compile_norm(on): | |
| global norm_patches | |
| updated=[] | |
| for mod,plain,compiled in norm_patches: | |
| if on and compiled is None:compiled=torch.compile(plain,dynamic=True) | |
| mod.forward=compiled if on else plain | |
| updated.append((mod,plain,compiled)) | |
| norm_patches=updated | |
| stream_pool=ThreadPoolExecutor(2) | |
| stream_k=torch.cuda.Stream();stream_u=torch.cuda.Stream() | |
| stream_k.wait_stream(torch.cuda.current_stream());stream_u.wait_stream(torch.cuda.current_stream()) | |
| def probe_graph(): | |
| apply_compile_norm(False) | |
| static=torch.tensor([AutoTokenizer.from_pretrained(G_PATH).encode('Hello, how are you?',add_special_tokens=False)],device='cuda:0') | |
| def forward():return km(input_ids=static,logits_to_keep=1,use_cache=False,kernel_options={'BLOCK_M':32,'BLOCK_N':32}).logits.float() | |
| with torch.inference_mode(): | |
| for _ in range(3):ref=forward() | |
| torch.cuda.synchronize();ref=ref.clone() | |
| t=time.perf_counter() | |
| for _ in range(20):out=forward() | |
| torch.cuda.synchronize();eager=1000*(time.perf_counter()-t)/20 | |
| graph=torch.cuda.CUDAGraph() | |
| with torch.cuda.graph(graph):captured=forward() | |
| graph.replay();torch.cuda.synchronize();diff=float((ref-captured).abs().max()) | |
| t=time.perf_counter() | |
| for _ in range(20):graph.replay() | |
| torch.cuda.synchronize();graphed=1000*(time.perf_counter()-t)/20 | |
| return {'status':'ok','scope':'diagnostic repeated tiny synthetic K forward only, not representative latency','tokens':static.shape[1],'eager_ms':eager,'graph_ms':graphed,'max_abs_logit_diff':diff} | |
| for line in sys.stdin: | |
| try: | |
| r=json.loads(line);kind=r.pop('_kind','concurrent') | |
| if kind=='graph_probe': | |
| try:probe=probe_graph() | |
| except BaseException as e:probe={'status':'error','scope':'K tiny diagnostic graph capture','error':repr(e)} | |
| print(json.dumps(probe),flush=True);continue | |
| ubatch=int(r.pop('_ubatch',8));opt_active=r.pop('_opt','fastconv_longcache');u.runtime.batch_size=ubatch | |
| for mod,plain,fast in ba_patches:mod.forward=fast if opt_active in ['miner_ba','fast_all','fast_all_longcache'] else plain | |
| apply_compile_norm(opt_active in ['compile_norm','fast_all','fast_all_longcache']) | |
| qwen_modeling.causal_conv1d_fn=optimized_conv if opt_active in ['fastconv','fastconv_state_once','fast_all','fastconv_longcache','fast_all_longcache'] else reference_conv | |
| K_DONE.clear() | |
| if kind=='single_u':K_DONE.set() | |
| torch.cuda.synchronize();torch.cuda.reset_peak_memory_stats();start=time.perf_counter() | |
| a=b=None | |
| if kind=='concurrent': | |
| def call_k(): | |
| with torch.cuda.stream(stream_k): | |
| torch._dynamo.config.recompile_limit=128 | |
| return invoke_k(r) | |
| def call_u(): | |
| with torch.cuda.stream(stream_u):return invoke_u(r) | |
| fa=stream_pool.submit(call_k);fb=stream_pool.submit(call_u) | |
| # Drain both futures even on an error before accepting any next request. | |
| ae=be=None | |
| try:a=fa.result() | |
| except BaseException as e:ae=e | |
| try:b=fb.result() | |
| except BaseException as e:be=e | |
| torch.cuda.synchronize() | |
| if ae or be:raise (ae or be) | |
| mid=start | |
| elif kind=='single_k': | |
| a=invoke_k(r);torch.cuda.synchronize();mid=time.perf_counter() | |
| elif kind=='single_u': | |
| mid=start;b=invoke_u(r) | |
| else: | |
| a=invoke_k(r);torch.cuda.synchronize();mid=time.perf_counter();b=invoke_u(r) | |
| torch.cuda.synchronize();end=time.perf_counter() | |
| combined=mix(r,a,b) if a and b else None;duo_end=time.perf_counter() | |
| result={'K':a,'U':b,'Duo':combined,'timings_ms':{'K':1000*(mid-start),'U':1000*(end-mid),'Duo':1000*(duo_end-start)},'peak_bytes':torch.cuda.max_memory_allocated(),'peak_reserved_bytes':torch.cuda.max_memory_reserved(),'optimization':{'name':opt_active,'miner_ba_patched_modules':len(ba_patches),'compile_norm_modules':len(norm_patches),'conv_probe':conv_probe,'u_route':getattr(u.runtime,'fast_route',None)}} | |
| print(json.dumps({'status':'ok',**result}),flush=True) | |
| except BaseException as e: | |
| traceback.print_exc();torch.cuda.synchronize();torch.cuda.empty_cache() | |
| print(json.dumps({'status':'error','error':str(e),'exception':type(e).__name__}),flush=True) | |