Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions call.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
""" Example - circle model import/export """

import pycircle

from pycircle.circleir.model import Model
from pycircle.circleir.operators import CircleAdd, CircleCall
from pycircle.circleir.subgraph import Subgraph
from pycircle.circleir.tensor import Tensor
from pycircle.util.alias import TensorType


### subgraph 0
### input0, input1 -> call0 (subgraph 1) -> tensor0
### tensor0, weights0 -> add0 -> tensor1
graph0 = Subgraph()
graph0.name = "graph0"
graph0.inputs = [
Tensor("sub1_input0", [1, 3], TensorType.FLOAT32),
Tensor("sub1_input1", [1, 3], TensorType.FLOAT32),
]

call0 = CircleCall()
call0.inputs = [graph0.inputs[0], graph0.inputs[1]]
call0.subgraph = 1
call0.outputs(0).attribute("Call0", [1, 3], TensorType.FLOAT32)


add1 = CircleAdd()
weights0 = Tensor("weights0", [1, 3], TensorType.FLOAT32, [100.0, 100.0, 100.0])
add1.inputs = [call0.outputs(0), weights0]
add1.outputs(0).attribute("add0", [1, 3], TensorType.FLOAT32)

graph0.outputs = [add1.outputs(0)]

### subgraph 1
### input0, input1 -> ADD -> output
graph1 = Subgraph()
graph1.name = "graph1"
graph1.inputs = [
Tensor("input0", [1, 3], TensorType.FLOAT32),
Tensor("input1", [1, 3], TensorType.FLOAT32, [-100.0, -100.0, -100.0]),
]
sub_add = CircleAdd()
sub_add.inputs = [graph1.inputs[0], graph1.inputs[1]]
sub_add.outputs(0).attribute("SubAdd", [1, 3], TensorType.FLOAT32)
graph1.outputs = [sub_add.outputs(0)]

### model
circle_model = Model()
circle_model.subgraphs = [graph0, graph1]
circle_model.signature_defs = {
"graph0": {"subgraph_index": 0},
"graph1": {"subgraph_index": 1},
}

pycircle.export_circle_model(circle_model, "call.circle")

import torch

try:
from onert import infer
except ImportError:
raise RuntimeError("The 'onert' package is required to run this function.")

session_float = infer.session("call.circle")
output = session_float.infer(
(
torch.randn(1, 3),
torch.randn(1, 3),
),
measure=True,
)
print(output)
37 changes: 37 additions & 0 deletions example_liquid.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from transformers import AutoProcessor, AutoModelForImageTextToText
from transformers.image_utils import load_image
from transformers.integrations.executorch import sdpa_mask_without_vmap
from transformers.masking_utils import ALL_MASK_ATTENTION_FUNCTIONS
# Load model and processor
model_id = "LiquidAI/LFM2-VL-450M"
model = AutoModelForImageTextToText.from_pretrained(
model_id,
device_map="auto",
torch_dtype="bfloat16",
trust_remote_code=True
)
processor = AutoProcessor.from_pretrained(model_id, trust_remote_code=True)

# Load image and create conversation
url = "https://www.ilankelman.org/stopsigns/australia.jpg"
image = load_image(url)
conversation = [
{
"role": "user",
"content": [
{"type": "image", "image": image},
{"type": "text", "text": "What is in this image?"},
],
},
]

# Generate Answer
inputs = processor.apply_chat_template(
conversation,
add_generation_prompt=True,
return_tensors="pt",
return_dict=True,
tokenize=True,
).to(model.device)
outputs = model.generate(**inputs, max_new_tokens=64)
processor.batch_decode(outputs, skip_special_tokens=True)[0]
80 changes: 80 additions & 0 deletions if.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
""" Example - circle model import/export """

import pycircle
from pycircle.circleir.model import Model
from pycircle.circleir.operators import CircleAdd, CircleIf
from pycircle.circleir.subgraph import Subgraph
from pycircle.circleir.tensor import Tensor
from pycircle.util.alias import TensorType

# 입력 텐서 및 상수 텐서 정의
input_tensor0 = Tensor("input0", [1, 3], TensorType.FLOAT32)
input_tensor1 = Tensor("input1", [1, 3], TensorType.FLOAT32)
weight_add_100 = Tensor("constant0", [1, 3], TensorType.FLOAT32, [100, 100, 100])
weight_sub_100 = Tensor("constant1", [1, 3], TensorType.FLOAT32, [-100, -100, -100])

### then_subgraph ###
then_subgraph = Subgraph()
then_subgraph.inputs = [Tensor("input0", [1, 3], TensorType.FLOAT32), weight_add_100]

add_op_then = CircleAdd()
add_op_then.inputs = [then_subgraph.inputs[0], then_subgraph.inputs[1]]
add_op_then.outputs(0).attribute("add_output_then", [1, 3], TensorType.FLOAT32)
then_subgraph.outputs = [add_op_then.outputs(0)]

### else_subgraph ###
else_subgraph = Subgraph()
else_subgraph.inputs = [Tensor("input0", [1, 3], TensorType.FLOAT32), weight_sub_100]

add_op_else = CircleAdd()
add_op_else.inputs = [
else_subgraph.inputs[0],
Tensor("input0", [1, 3], TensorType.FLOAT32),
]
add_op_else.outputs(0).attribute("add_output_else", [1, 3], TensorType.FLOAT32)
else_subgraph.outputs = [add_op_else.outputs(0)]

### root_subgraph with CircleIf ###
root_subgraph = Subgraph()
root_subgraph.name = "root_subgraph"
condition_tensor = Tensor("condition", [1], TensorType.BOOL)
root_subgraph.inputs = [condition_tensor, input_tensor0, input_tensor1]

circle_if_op = CircleIf(1, 2)
circle_if_op.inputs = [condition_tensor, input_tensor0, input_tensor1]
circle_if_op.outputs(0).attribute("output_tensor", [1, 3], TensorType.FLOAT32)
circle_if_op.then_subgraph_index = 1
circle_if_op.else_subgraph_index = 2
root_subgraph.outputs = [circle_if_op.outputs(0)]

# 모델 구성
circle_model = Model()
circle_model.description = "pycircle example : signature_def"
circle_model.subgraphs = [root_subgraph, then_subgraph, else_subgraph]
circle_model.signature_defs = {
"root_graph": {"subgraph_index": 0},
"then_graph": {"subgraph_index": 1},
"else_graph": {"subgraph_index": 2},
}

# 모델 export
pycircle.export_circle_model(circle_model, "signature_def.circle")

# onert를 통한 추론 (Inference)
import torch

try:
from onert import infer
except ImportError:
raise RuntimeError("The 'onert' package is required to run this function.")

session = infer.session("signature_def.circle")
output = session.infer(
(
torch.tensor([True]), # condition tensor
torch.randn(1, 3), # input tensor 0
torch.tensor([[100.0, 100.0, 100.0]]), # weights tensor
),
measure=True,
)
print(output)
132 changes: 132 additions & 0 deletions shortconv.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import torch
from torch import nn
from torch.export import export # PyTorch 2.x에서 사용


def apply_mask_to_padding_states(hidden_states, attention_mask):
"""
Tunes out the hidden states for padding tokens, see https://github.com/state-spaces/mamba/issues/66
"""
if attention_mask is not None and attention_mask.shape[1] > 1 and attention_mask.shape[0] > 1:
dtype = hidden_states.dtype
hidden_states = (hidden_states * attention_mask[:, :, None]).to(dtype)

return hidden_states

# 분기 1: past_key_value 있고 cache_position[0] > 0 일 때 처리용 모듈
class TrueBranch(nn.Module):
def __init__(self, conv, conv_cache, layer_idx, L_cache, bias):
super().__init__()
self.conv = conv
self.register_buffer(
"conv_cache",
torch.zeros(10, 32, 1024, 20),
)
self.layer_idx = layer_idx
self.L_cache = L_cache
self.bias = bias

def forward(self, Bx, cache_position, seq_len):
conv_state = self.conv_cache[self.layer_idx,:,:,:]
cache_position = torch.clamp(cache_position, 0, self.L_cache - 1)
conv_state = torch.roll(conv_state, shifts=-1, dims=-1)
conv_state[:, :, cache_position] = Bx.to(device=conv_state.device, dtype=conv_state.dtype)
self.conv_cache[self.layer_idx, :, :, :] = conv_state.clone()
conv_out = torch.sum(conv_state.to(Bx.device) * self.conv.weight[:, 0, :], dim=-1)
if self.bias is not None:
conv_out += self.bias
conv_out = conv_out.unsqueeze(-1)
return conv_out

# 분기 2: 그 외 케이스 처리 모듈
class FalseBranch(nn.Module):
def __init__(self, conv, conv_cache, layer_idx, L_cache):
super().__init__()
self.conv = conv
self.register_buffer(
"conv_cache",
torch.zeros(10, 32, 1024, 20),
)
self.layer_idx = layer_idx
self.L_cache = L_cache

def forward(self, Bx, cache_position, seqlen):
conv_state = nn.functional.pad(Bx, (self.L_cache - Bx.shape[-1], 0))
self.conv_cache[self.layer_idx, :, :, :] = conv_state.clone()
conv_out = self.conv(Bx)[..., :seqlen]
return conv_out

class ShortConv(nn.Module):
def __init__(self, in_proj, conv, conv_cache, out_proj, layer_idx, L_cache, bias):
super().__init__()
self.in_proj = in_proj
self.conv = conv
self.conv_cache = conv_cache
self.out_proj = out_proj
self.layer_idx = layer_idx
self.L_cache = L_cache
self.bias = bias

self.true_branch = TrueBranch(conv, conv_cache, layer_idx, L_cache, bias)
self.false_branch = FalseBranch(conv, conv_cache, layer_idx, L_cache)

def forward(self, x, past_key_value=None, cache_position=None, attention_mask=None):
seqlen = torch.tensor(x.shape[1])
x = apply_mask_to_padding_states(x, attention_mask)
BCx = self.in_proj(x).transpose(-1, -2)
B, C, x = BCx.chunk(3, dim=-2)
Bx = B * x


# 조건: past_key_value가 있고 cache_position[0] > 0 인 경우
pred = (past_key_value is not None) and (cache_position[0] > 0)
# if pred is True:
# conv_out = true_fn()
# else:
# conv_out = false_fn()
conv_out = torch.cond(pred, self.true_branch, self.false_branch, (Bx, cache_position, seqlen,))

y = C * conv_out
y = y.transpose(-1, -2).contiguous()
y = self.out_proj(y)
return y

import torch
from torch import nn
from torch.export import export

# 앞서 정의한 TrueBranch, FalseBranch, MoEModel 클래스가 있다고 가정

# 모듈 인스턴스화 시 필요한 임의 파라미터 초기화 (예시)
in_proj = nn.Linear(1024, 1024 * 3) # 임베딩 크기 1024 가정
conv = nn.Conv1d(1024, 1024, kernel_size=(3,), stride=(1,), padding=(2,), groups=1024, bias=False) # 1D conv, feature 채널 64
conv_cache = [torch.zeros(32, 1024, 20)] * 10 # 배치 32, feature 64, 캐시 크기 20, 레이어 10개 가정
out_proj = nn.Linear(1024, 1024) # 출력 임베딩 크기 1024

layer_idx = 0
L_cache = 20
bias = conv.bias

# MoEModel 생성
model = MoEModel(in_proj, conv, conv_cache, out_proj, layer_idx, L_cache, bias)

# 예시 입력 생성 (배치 32, 시퀀스 길이 10, 임베딩 1024)
x = torch.randn(32, 10, 1024)

# past_key_value와 cache_position도 필요한 경우 생성 (None 가능)
past_key_value = type('', (), {})()
past_key_value.conv_cache = conv_cache
cache_position = torch.tensor([5])

model.forward(x, past_key_value, cache_position, None) #ADDED
# model.eval()
# # torch.export로 모델 export 예시
# exported_model = export(model, (x, past_key_value.conv_cache, cache_position, None))

# # ExportedProgram 타입 출력 확인
# print(type(exported_model))
# print(exported_model)

# import tico

# tico.convert_from_exported_program(exported_model).save("shortconv.circle")
58 changes: 58 additions & 0 deletions signature.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
""" Example - circle model import/export """

import pycircle

from pycircle.circleir.model import Model
from pycircle.circleir.operators import CircleAdd
from pycircle.circleir.subgraph import Subgraph
from pycircle.circleir.tensor import Tensor
from pycircle.util.alias import TensorType

subgraph1 = Subgraph()
subgraph1.name = "subgraph1"
subgraph1.inputs = [
Tensor("subgraph1_input", [1, 3], TensorType.FLOAT32),
]

weights1 = Tensor("constant1", [1, 3], TensorType.FLOAT32, [0.1, 0.2, 0.3])

add1 = CircleAdd()
add1.inputs = [subgraph1.inputs[0], weights1]
add1.outputs(0).attribute("Add1", [1, 3], TensorType.FLOAT32)

subgraph1.outputs = [add1.outputs(0)]

subgraph2 = Subgraph()
subgraph2.name = "subgraph2"
subgraph2.inputs = [
Tensor("subgraph2_input1", [1, 3], TensorType.FLOAT32),
Tensor("subgraph2_input2", [1, 3], TensorType.FLOAT32),
]

add2 = CircleAdd()
add2.inputs = [subgraph2.inputs[0], subgraph2.inputs[1]]
add2.outputs(0).attribute("Add2", [1, 3], TensorType.FLOAT32)

subgraph2.outputs = [add2.outputs(0)]

circle_model = Model()
circle_model.description = "pycircle example : signature_def"
# circle_model.subgraphs = [subgraph2, subgraph1]
circle_model.subgraphs = [subgraph1, subgraph2]
circle_model.signature_defs = {
"add_constant": {"subgraph_index": 0},
"add_two_inputs": {"subgraph_index": 1},
}

pycircle.export_circle_model(circle_model, "signature_def_original.circle")

import torch

try:
from onert import infer
except ImportError:
raise RuntimeError("The 'onert' package is required to run this function.")

session_float = infer.session("signature_def_original.circle")
output = session_float.infer((torch.randn(1, 3),))
breakpoint()
8 changes: 8 additions & 0 deletions test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
def test():
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant file

if 1 is 1:
pass

print("HI")


test()
Loading