I wanted to install it to give it a try, but in the playstore I saw the application roughly translated is "susceptible to share my approximative location with other enterprises or organization".
I must ask, what could the reason(s) for a keyboard have access to a location ?
I’ve always thought about copying other useful apps that are clearly trying to collect data or make you pay for stupid IAP, and then publishing and maintaining it through donations. The apps would all be free in the various offical stores.
Same here, partial code from stackcodegen.ml in the said archive :
open Op;;
open Var;;
open Ctx;;
open Ltal;;
open Util;;
let debug msg = ();;
let rs = mkvar "rs";;
let ra = mkvar "ra";;
let rf = mkvar "rf";;
let rt = mkvar "rt";;
let rr = mkvar "rr";;
let ru = mkvar "ru";;
let retty stackty aty = (Code(Ctx.from_list[(rs,stackty);
(ra,aty);
(rt,toptp);
(rf,listtp);
(rr,toptp)]))
let rec tt tctx ctx tp =
match tp with
Il.TVar a -> if bound tctx a then TVar a else lookup ctx a
| Il.Int -> DTp Word
| Il.Top -> DTp Top (* for now )
| Il.Tensor(t1,t2) -> Ref(Tcltal.mkpair (tt tctx ctx t1, tt tctx ctx t2))
| Il.Exists (alpha, tp) ->
let beta = rename alpha in
Exists (beta, W, tt tctx (extend ctx alpha (TVar beta)) tp)
| Il.List t ->
let tv = mkvar "list" in
Mu(tv,NRef(Tcltal.mkpair(tt tctx ctx t, TVar tv)))
| _ -> DTp(arrowtt tctx ctx tp)
and arrowtt tctx ctx t =
match t with
Il.Forall(alpha,t) ->
let beta = Var.rename alpha in
Forall(beta, W, arrowtt tctx (extend ctx alpha (TVar beta)) t)
| Il.Arrow(t1,t2) ->
let t1' = tt tctx ctx t1 in
let t2' = tt tctx ctx t2 in
let stk = mkvar "s" in
Forall (stk,M,
Code(Ctx.from_list[(rs,Stack(Tensor(t1',MTVar stk)));
(ra,toptp);
(rt,toptp);
(rf,listtp);
(rr,DTp(retty (Stack(MTVar stk)) t2'))]))
| _ -> tcfail "expected a function type in forall"
let typetrans tctx tp = tt tctx Ctx.emp tp
let arrowtypetrans tctx t1 t2 = arrowtt tctx Ctx.emp (Il.Arrow (t1,t2))
( Need to specify the type ty of "the rest of the stack", in most cases
alpha )
type code_env = {cctx : cctx;
cs : code_section;
fctx : Il.ctx;
lctx : var Ctx.ctx;
fp : int}
let get_fctx cenv = cenv.fctx
let get_lctx cenv = cenv.lctx
Thanks for the tip ! I'm very often on the phone for HN and I could not have done it easily. But I promise next time I'll post a big chunk of code I'll do it from my laptop, from where I can easily add 2 spaces at the beginning of each line.
open Op;; open Var;; open Ctx;; open Ltal;; open Util;;
let debug msg = ();;
let rs = mkvar "rs";; let ra = mkvar "ra";; let rf = mkvar "rf";; let rt = mkvar "rt";; let rr = mkvar "rr";; let ru = mkvar "ru";;
let retty stackty aty = (Code(Ctx.from_list[(rs,stackty); (ra,aty); (rt,toptp); (rf,listtp); (rr,toptp)]))
let rec tt tctx ctx tp = match tp with Il.TVar a -> if bound tctx a then TVar a else lookup ctx a | Il.Int -> DTp Word | Il.Top -> DTp Top (* for now ) | Il.Tensor(t1,t2) -> Ref(Tcltal.mkpair (tt tctx ctx t1, tt tctx ctx t2)) | Il.Exists (alpha, tp) -> let beta = rename alpha in Exists (beta, W, tt tctx (extend ctx alpha (TVar beta)) tp) | Il.List t -> let tv = mkvar "list" in Mu(tv,NRef(Tcltal.mkpair(tt tctx ctx t, TVar tv))) | _ -> DTp(arrowtt tctx ctx tp)
and arrowtt tctx ctx t = match t with Il.Forall(alpha,t) -> let beta = Var.rename alpha in Forall(beta, W, arrowtt tctx (extend ctx alpha (TVar beta)) t) | Il.Arrow(t1,t2) -> let t1' = tt tctx ctx t1 in let t2' = tt tctx ctx t2 in let stk = mkvar "s" in Forall (stk,M, Code(Ctx.from_list[(rs,Stack(Tensor(t1',MTVar stk))); (ra,toptp); (rt,toptp); (rf,listtp); (rr,DTp(retty (Stack(MTVar stk)) t2'))]))
| _ -> tcfail "expected a function type in forall"
let typetrans tctx tp = tt tctx Ctx.emp tp let arrowtypetrans tctx t1 t2 = arrowtt tctx Ctx.emp (Il.Arrow (t1,t2))
( Need to specify the type ty of "the rest of the stack", in most cases alpha )
type code_env = {cctx : cctx; cs : code_section; fctx : Il.ctx; lctx : var Ctx.ctx; fp : int}
let get_fctx cenv = cenv.fctx let get_lctx cenv = cenv.lctx
type block_env = {cenv : code_env; ilist : instruction list; lab : clab; tctx : Ltal.tctx; rctx : Ltal.rctx}
let get_from_cenv f benv = f benv.cenv
exception CodeFail of string code_env exception BlockFail of string * block_env
(* val begin_fn : code_env -> clab -> register_file -> block_env val end_fn : block_env -> code_env val emit_label : fn_env -> clab -> dtp -> block_env val emit : block_env -> instruction -> block_env -> block_env val emit_end : end_instruction -> block_env -> fn_env val drop : reg -> block_env -> block_env val free : reg -> block_env -> block_env val push : reg -> reg -> block_env -> block_env val pop : reg -> reg -> block_env -> block_env val malloc : reg -> block_env -> block_env )
let do_print y x = (debug y; x)
let (>>) f g x = g(f(x)) let (>>=) f h x = let y = f x in h y x
let rec mkltp tctx rctx = Ctx.fold (fun t sk dtp -> let k = match sk with _,W -> W | _,M -> M in Forall(t,k,dtp)) tctx (Code (rctx))
let current_ltp benv = debug ("Generalizing "^(Ctx.pp_ctx (fun _ -> "") benv.tctx)^"\n"); ( rt is caller-save *) let rctx = update benv.rctx rt toptp in (mkltp benv.tctx rctx)
I had the same feeling, so I began to read https://www.forth.com/starting-forth/1-forth-stacks-dictiona... with gforth installed with apt. And made few exercises to manipulate the stack with some words and get a grasp on it. Now I saw how it works, I came back to my imperative languages and won't come back to it.
IMO my skills in forth are not really enough to see the distinction between any implementation of forth, so the first one I stumbled upon was ok.
I tried Emacs a bit after using Sublime Text for a while. I'm still using Sublime Text to this day because muscle memory, but the experience got me a deeper understanding of the capabilities of Sublime.
While Emacs is profoundly hackable it feels a little bit "rough" on the edges. Sublime feels less hackable but more "clean".
I do not agree on the "lossless" adjective. And even if it is lossless, for sure it is not deterministic.
For example I would not want a zip of an encyclopedia that uncompresses to unverified, approximate and sometimes even wrong text. According to this site : https://www.wikiwand.com/en/articles/Size%20of%20Wikipedia a compressed Wikipedia without medias, just text is ~24GB. What's the medium size of an LLM, 10 GB ? 50 GB ? 100 GB ? Even if it's less, it's not an accurate and deterministic way to compress text.
(to be clear this is not me arguing for any particular merits of llm-based compression, but) you appear to have conflated one particular nondeterministic llm-based compression scheme that you imagined with all possible such schemes, many of which would easily fit any reasonable definitions of lossless and deterministic by losslessly doing deterministic things using the probability distributions output by an llm at each step along the input sequence to be compressed.
With a temperature of zero, LLM output will always be the same. Then it becomes a matter of getting it to output the exact replica of the input: if we can do that, it will always produce it, and the fact it can also be used as a bullshit machine becomes irrelevant.
With the usual interface it’s probably inefficient: giving just a prompt alone might not produce the output we need, or it might be larger than the thing we’re trying to compress. However, if we also steer the decisions along the way, we can probably give a small prompt that gets the LLM going, and tweak its decision process to get the tokens we want. We can then store those changes alongside the prompt. (This is a very hand-wavy concept, I know.)
There's an easier and more effective way of doing that - instead of trying to give the model an extrinsic prompt which makes it respond with your text, you use the text as input and, for each token, encode the rank of the actual token within the set of tokens that the model could have produced at that point. (Or an escape code for tokens which were completely unexpected.) If you're feeling really crafty, you can even use arithmetic coding based on the probabilities of each token, so that encoding high-probability tokens uses fewer bits.
From what I understand, this is essentially how ts_zip (linked elsewhere) works.
The models are differentiable, they are trained with backprop. You can easily just run it in reverse to get the input that produces near certainty of producing the output. For a given sequence length, you can create a new optimzation that takes the input sequence, passes to model (frozen) and runs steps over the input sequence to reduce the "loss" which is the desired output. This will give you the optimal sequence of that length to maximize the probability of seeing the output sequence. Of course, if you're doing this to chatGPT or another API-only model, you have no choice but to hunt around.
Of course the optimal sequence to produce the output will be a series of word vectors (of multi-hundreds of dimensions). You could match each to its closest word in any language (or make this a constraint during solving), or just use the vectors themselves as the compressed data value.
Ultimately, NNets of various kinds are used for compression in various contexts. There are some examples where guassian-splatting-like 3d scenes are created by comrpessing all the data into the weights of a nnet via a process similar to what I described to create a fully explorable 3d color scene that can be rendered from any angle.
A bit of nitpicking, a temperature of zero does not really exist (it would lead to division by zero in softmax). It's sampling (and non-deterministic compute kernels) that makes token prediction non-deterministic. You could simply fix it (assuming deterministic kernels) by using greedy decoding (argmax with a stable sort in the case of ties).
As temperatures approach zero, the probability of the most likely token approaches one (assuming no ties). So my guess is that LLM inference providers started using temperature=0 to disable sampling because people would try to approximate greedy decoding by using teensy temperatures.
- https://github.com/orgzly-revived/orgzly-android-revived
reply